[SCM] Packaging for pytango branch, upstream, updated. upstream/7.2.3-1-g9981e43

Picca Frédéric-Emma?==?UTF-8?Q?nuel picca at debian.org
Sun Sep 23 12:18:46 UTC 2012


The following commit has been merged in the upstream branch:
commit 9981e43d728c5862d57690ba01d049f6e2ae28cd
Author: Picca Frédéric-Emmanuel <picca at debian.org>
Date:   Fri Sep 21 21:46:31 2012 +0200

    Imported Upstream version 8.0.0

diff --git a/PKG-INFO b/PKG-INFO
index b6061c1..41a2ca2 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,13 +1,13 @@
 Metadata-Version: 1.1
 Name: PyTango
-Version: 7.2.3
+Version: 8.0.0
 Summary: A python binding for the Tango control system
 Home-page: http://www.tango-controls.org/static/PyTango/latest/doc/html/
 Author: Tiago Coutinho
 Author-email: tcoutinho at cells.es
 License: LGPL
 Download-URL: http://pypi.python.org/packages/source/P/PyTango
-Description: This module implements the Python Tango Device API mapping
+Description: This module implements the Python Tango Device API mapping.
 Keywords: Tango,CORBA,binding
 Platform: Linux
 Platform: Windows XP/Vista/7
diff --git a/PyTango/__init__.py b/PyTango/__init__.py
index 4189e71..4a0d750 100644
--- a/PyTango/__init__.py
+++ b/PyTango/__init__.py
@@ -28,6 +28,8 @@ Documentation for this package can be found online:
 http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html
 """
 
+from __future__ import print_function
+
 __all__ = [ 'AccessControlType', 'ApiUtil', 'ArchiveEventInfo',
 'ArchiveEventProp', 'ArgType', 'AsynCall', 'AsynReplyNotArrived', 'AttReqType',
 'Attr', 'AttrConfEventData', 'AttrData', 'AttrDataFormat', 'AttrList',
@@ -51,17 +53,18 @@ __all__ = [ 'AccessControlType', 'ApiUtil', 'ArchiveEventInfo',
 'DevVarLongStringArray', 'DevVarShortArray', 'DevVarStringArray',
 'DevVarULong64Array', 'DevVarULongArray', 'DevVarUShortArray',
 'DevVoid', 'DeviceAttribute', 'DeviceAttributeConfig',
-'DeviceAttributeHistory', 'DeviceClass', 'DeviceData', 'DeviceDataHistory',
-'DeviceDataHistoryList', 'DeviceImpl', 'DeviceInfo', 'DeviceProxy',
+'DeviceAttributeHistory', 'DeviceClass', 'DeviceData', 'DeviceDataList',
+'DeviceDataHistory', 'DeviceDataHistoryList',
+'DeviceImpl', 'DeviceInfo', 'DeviceProxy',
 'DeviceUnlocked', 'Device_2Impl', 'Device_3Impl', 'Device_4Impl',
 'DispLevel', 'EncodedAttribute', 'ErrSeverity', 'ErrorIt',
 'EventData', 'EventProperties', 'EventSystemFailed', 'EventType',
 'Except', 'ExtractAs', 'FMT_UNKNOWN', 'FatalIt', 'Group', 'GroupAttrReply',
-'GroupAttrReplyList', 'GroupCmdReply', 'GroupCmdReplyList', 'GroupElement',
+'GroupAttrReplyList', 'GroupCmdReply', 'GroupCmdReplyList',
 'GroupReply', 'GroupReplyList', 'IMAGE', 'ImageAttr', 'InfoIt',
 'KeepAliveCmdCode', 'Level', 'LockCmdCode', 'LockerInfo', 'LockerLanguage',
 'LogIt', 'LogLevel', 'LogTarget', 'Logger', 'Logging', 'MessBoxType',
-'MultiAttribute', 'MultiClassAttribute', 'NamedDevFailed',
+'MultiAttribute', 'MultiAttrProp', 'MultiClassAttribute', 'NamedDevFailed',
 'NamedDevFailedList', 'NonDbDevice', 'NonSupportedFeature',
 'NotAllowed', 'NumpyType', 'PeriodicEventInfo', 'PeriodicEventProp',
 'PollCmdCode', 'PollDevice',
@@ -76,30 +79,30 @@ __all__ = [ 'AccessControlType', 'ApiUtil', 'ArchiveEventInfo',
 'class_factory', 'class_list', 'constants', 'constructed_class',
 'cpp_class_list', 'delete_class_list', 'get_class', 'get_classes',
 'get_constructed_class', 'get_constructed_classes', 'get_cpp_class',
-'get_cpp_classes', 'isBufferLikeType', 'is_array_type', 'is_float_type',
+'get_cpp_classes', 'is_array_type', 'is_float_type',
 'is_int_type', 'is_numerical_type', 'is_scalar_type', 'numpy_image',
 'numpy_spectrum', 'numpy_type', 'obj_2_str', 'raise_asynch_exception',
 'seqStr_2_obj']
 
 __docformat__ = "restructuredtext"
 
+import sys
+
 try:
-    from _PyTango import DeviceProxy
-except ImportError, ie:
+    from ._PyTango import DeviceProxy
+except ImportError as ie:
     if not ie.args[0].count("_PyTango"):
         raise ie
-    print 80*"-"
-    print ie
-    print 80*"-"
-    print "Probably your current directory is the PyTango's source installation directory."
-    print "You must leave this directory first before using PyTango, otherwise the"
-    print "source distribution will conflict with the installed PyTango"
-    print 80*"-"
-    import sys
+    print(80*"-")
+    print(ie)
+    print(80*"-")
+    print("Probably your current directory is the PyTango's source installation directory.")
+    print("You must leave this directory first before using PyTango, otherwise the")
+    print("source distribution will conflict with the installed PyTango")
+    print(80*"-")
     sys.exit(1)
 
-from _PyTango import \
-    (AccessControlType, ApiUtil, ArchiveEventInfo,
+from ._PyTango import (AccessControlType, ApiUtil, ArchiveEventInfo,
     AsynCall, AsynReplyNotArrived, AttReqType, Attr, AttrConfEventData,
     AttrDataFormat, AttrList, AttrProperty, AttrQuality, AttrReadEvent,
     AttrSerialModel, AttrWriteType, AttrWrittenEvent, Attribute,
@@ -118,12 +121,12 @@ from _PyTango import \
     DevVarLongArray, DevVarLongStringArray, DevVarShortArray, DevVarStringArray,
     DevVarULong64Array, DevVarULongArray, DevVarUShortArray, DevVoid,
     DeviceAttribute, DeviceAttributeConfig, DeviceAttributeHistory,
-    DeviceData, DeviceDataHistory, DeviceDataHistoryList,
+    DeviceData, DeviceDataList, DeviceDataHistory, DeviceDataHistoryList,
     DeviceImpl, DeviceInfo, DeviceUnlocked, Device_2Impl,
     Device_3Impl, Device_4Impl, DispLevel, EncodedAttribute, ErrSeverity,
     EventData, EventSystemFailed, EventType,
     Except, ExtractAs, FMT_UNKNOWN, GroupAttrReply, GroupAttrReplyList,
-    GroupCmdReply, GroupCmdReplyList, GroupElement, GroupReply, GroupReplyList,
+    GroupCmdReply, GroupCmdReplyList, GroupReply, GroupReplyList,
     IMAGE, ImageAttr, KeepAliveCmdCode, Level, LockCmdCode, LockerInfo,
     LockerLanguage, LogLevel, LogTarget, Logger, Logging, MessBoxType,
     MultiAttribute, MultiClassAttribute, NamedDevFailed, NamedDevFailedList,
@@ -134,12 +137,12 @@ from _PyTango import \
     StdGroupCmdReplyVector, StdGroupReplyVector, StdLongVector,
     StdNamedDevFailedVector, StdStringVector, SubDevDiag, TimeVal,
     UserDefaultAttrProp, WAttribute, WRITE, WrongData, WrongNameSyntax,
-    alarm_flags, asyn_req_type, cb_sub_model, constants, isBufferLikeType,
+    alarm_flags, asyn_req_type, cb_sub_model, constants,
     raise_asynch_exception)
 
 ArgType = CmdArgType
 
-from release import Release
+from .release import Release
 
 __author__ = Release.author_lines
 __version_info__ = Release.version_info
@@ -149,23 +152,24 @@ __version_number__ = Release.version_number
 __version_description__ = Release.version_description
 __doc__ = Release.long_description
 
-from attr_data import AttrData
-from log4tango import TangoStream, LogIt, DebugIt, InfoIt, WarnIt, \
+from .attr_data import AttrData
+from .log4tango import TangoStream, LogIt, DebugIt, InfoIt, WarnIt, \
     ErrorIt, FatalIt
-from device_server import ChangeEventProp, PeriodicEventProp, \
+from .device_server import ChangeEventProp, PeriodicEventProp, \
     ArchiveEventProp, AttributeAlarm, EventProperties, AttributeConfig, \
-    AttributeConfig_2, AttributeConfig_3
-from attribute_proxy import AttributeProxy
-from group import Group
-from pyutil import Util
-from device_class import DeviceClass
-from globals import get_class, get_classes, get_cpp_class, get_cpp_classes, \
+    AttributeConfig_2, AttributeConfig_3, MultiAttrProp
+from .attribute_proxy import AttributeProxy
+from .group import Group
+from .pyutil import Util
+from .device_class import DeviceClass
+from .globals import get_class, get_classes, get_cpp_class, get_cpp_classes, \
     get_constructed_class, get_constructed_classes, class_factory, \
     delete_class_list, class_list, cpp_class_list, constructed_class
-from utils import is_scalar_type, is_array_type, is_numerical_type, \
+from .utils import is_scalar_type, is_array_type, is_numerical_type, \
     is_int_type, is_float_type, obj_2_str, seqStr_2_obj
-from tango_numpy import NumpyType, numpy_type, numpy_spectrum, numpy_image
+from .utils import server_run
+from .tango_numpy import NumpyType, numpy_type, numpy_spectrum, numpy_image
 
-from pytango_init import init as __init
+from .pytango_init import init as __init
 __init()
 
diff --git a/PyTango/api_util.py b/PyTango/api_util.py
index 886ba77..6d5594c 100644
--- a/PyTango/api_util.py
+++ b/PyTango/api_util.py
@@ -25,13 +25,13 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["api_util_init"]
 
 __docformat__ = "restructuredtext"
 
-from _PyTango import ApiUtil
+from ._PyTango import ApiUtil
 
-from utils import document_method, document_static_method, _get_env_var
+from .utils import document_method, document_static_method, _get_env_var
 
 def __init_api_util():
     if not hasattr(ApiUtil, "get_env_var"):
@@ -143,7 +143,7 @@ def __doc_api_util():
         New in PyTango 7.1.3
     """ )
 
-def init(doc=True):
+def api_util_init(doc=True):
     __init_api_util()
     if doc:
         __doc_api_util()
\ No newline at end of file
diff --git a/PyTango/attr_data.py b/PyTango/attr_data.py
index 34d34f5..02cb01a 100644
--- a/PyTango/attr_data.py
+++ b/PyTango/attr_data.py
@@ -29,10 +29,9 @@ __all__ = [ "AttrData" ]
 
 __docformat__ = "restructuredtext"
 
-import operator
-
-from _PyTango import Except, CmdArgType, AttrDataFormat, AttrWriteType, \
+from ._PyTango import Except, CmdArgType, AttrDataFormat, AttrWriteType, \
     DispLevel, UserDefaultAttrProp, Attr, SpectrumAttr, ImageAttr
+from .utils import is_non_str_seq
 
 
 class AttrData(object):
@@ -66,7 +65,7 @@ class AttrData(object):
     def __create_user_default_attr_prop(self, attr_name, extra_info):
         """for internal usage only"""
         p = UserDefaultAttrProp()
-        for k, v in extra_info.iteritems():
+        for k, v in extra_info.items():
             k_lower = k.lower()
             method_name = "set_%s" % k_lower.replace(' ','_')
             if hasattr(p, method_name):
@@ -89,7 +88,7 @@ class AttrData(object):
         # check for well defined attribute info
         
         # check parameter
-        if not operator.isSequenceType(attr_info):
+        if not is_non_str_seq(attr_info):
             throw_ex("Wrong data type for value for describing attribute %s in "
                      "class %s\nMust be a sequence with 1 or 2 elements" 
                      % (attr_name, name))
@@ -103,14 +102,14 @@ class AttrData(object):
         if len(attr_info) == 2:
             # attr_info[1] must be a dictionary
             # extra_info = attr_info[1], with all the keys lowercase
-            for k, v in attr_info[1].iteritems():
+            for k, v in attr_info[1].items():
                 extra_info[k.lower()] = v
         
         attr_info = attr_info[0]
         
         attr_info_len = len(attr_info)
         # check parameter
-        if not operator.isSequenceType(attr_info) or \
+        if not is_non_str_seq(attr_info) or \
            attr_info_len < 3 or attr_info_len > 5:
             throw_ex("Wrong data type for describing mandatory information for "
                      "attribute %s in class %s\nMust be a sequence with 3, 4 "
@@ -231,4 +230,4 @@ class AttrData(object):
         
     DftAttrClassMap = { AttrDataFormat.SCALAR : Attr,
                         AttrDataFormat.SPECTRUM: SpectrumAttr,
-                        AttrDataFormat.IMAGE : ImageAttr }
\ No newline at end of file
+                        AttrDataFormat.IMAGE : ImageAttr }
diff --git a/PyTango/attribute_proxy.py b/PyTango/attribute_proxy.py
index 1334558..66fd972 100644
--- a/PyTango/attribute_proxy.py
+++ b/PyTango/attribute_proxy.py
@@ -29,20 +29,16 @@ To access these members use directly :mod:`PyTango` module and NOT
 PyTango.attribute_proxy.
 """
 
-__all__ = [ "AttributeProxy" ]
+__all__ = [ "AttributeProxy", "attribute_proxy_init"]
             
 __docformat__ = "restructuredtext"
 
-import operator
-import types
+from ._PyTango import StdStringVector, DbData, DbDatum, DeviceProxy
+from ._PyTango import __AttributeProxy as _AttributeProxy
+from .utils import seq_2_StdStringVector, seq_2_DbData, DbData_2_dict, \
+    is_pure_str, is_non_str_seq
+import collections
 
-from _PyTango import StdStringVector
-from _PyTango import DbData, DbDatum
-from PyTango.utils import seq_2_StdStringVector
-from PyTango.utils import seq_2_DbData, DbData_2_dict
-
-from _PyTango import __AttributeProxy as _AttributeProxy
-from _PyTango import DeviceProxy
 
 def __AttributeProxy__get_property(self, propname, value=None):
     """
@@ -77,7 +73,7 @@ def __AttributeProxy__get_property(self, propname, value=None):
                      DevFailed from database device
     """
 
-    if type(propname) in types.StringTypes or isinstance(propname, StdStringVector):
+    if is_pure_str(propname) or isinstance(propname, StdStringVector):
         new_value = value
         if new_value is None:
             new_value = DbData()
@@ -88,12 +84,12 @@ def __AttributeProxy__get_property(self, propname, value=None):
         new_value.append(propname)
         self._get_property(new_value)
         return DbData_2_dict(new_value)
-    elif operator.isSequenceType(propname):
+    elif isinstance(propname, collections.Sequence):
         if isinstance(propname, DbData):
             self._get_property(propname)
             return DbData_2_dict(propname)
 
-        if type(propname[0]) in types.StringTypes:
+        if is_pure_str(propname[0]):
             new_propname = StdStringVector()
             for i in propname: new_propname.append(i)
             new_value = value
@@ -140,16 +136,16 @@ def __AttributeProxy__put_property(self, value):
         new_value = DbData()
         new_value.append(value)
         value = new_value
-    elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+    elif is_non_str_seq(value):
         new_value = seq_2_DbData(value)
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k, v in value.iteritems():
+        for k, v in value.items():
             if isinstance(v, DbDatum):
                 new_value.append(v)
                 continue
             db_datum = DbDatum(k)
-            if operator.isSequenceType(v) and not type(v) in types.StringTypes:
+            if is_non_str_seq(v):
                 seq_2_StdStringVector(v, db_datum.value_string)
             else:
                 db_datum.value_string.append(str(v))
@@ -196,21 +192,21 @@ def __AttributeProxy__delete_property(self, value):
                     DevFailed from device (DB_SQLError)
     """
     if isinstance(value, DbData) or isinstance(value, StdStringVector) or \
-       type(value) in types.StringTypes:
+       is_pure_str(value):
         new_value = value
     elif isinstance(value, DbDatum):
         new_value = DbData()
         new_value.append(value)
-    elif operator.isSequenceType(value):
+    elif isinstance(value, collections.Sequence):
         new_value = DbData()
         for e in value:
             if isinstance(e, DbDatum):
                 new_value.append(e)
             else:
                 new_value.append(DbDatum(str(e)))
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k, v in value.iteritems():
+        for k, v in value.items():
             if isinstance(v, DbDatum):
                 new_value.append(v)
             else:
@@ -362,5 +358,5 @@ def __init_AttributeProxy(doc=True):
     AttributeProxy.get_last_event_date  = _method_device('get_last_event_date', doc=doc)
     AttributeProxy.is_event_queue_empty = _method_device('is_event_queue_empty', doc=doc)
 
-def init(doc=True):
+def attribute_proxy_init(doc=True):
     __init_AttributeProxy(doc=doc)
diff --git a/PyTango/base_types.py b/PyTango/base_types.py
index 8b41a5b..af433d2 100644
--- a/PyTango/base_types.py
+++ b/PyTango/base_types.py
@@ -25,13 +25,12 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["base_types_init"]
 
 __docformat__ = "restructuredtext"
 
-import operator
 
-from _PyTango import (StdStringVector, StdLongVector, StdDoubleVector, \
+from ._PyTango import (StdStringVector, StdLongVector, StdDoubleVector, \
     CommandInfoList, AttributeInfoList, AttributeInfoListEx, DbData, \
     DbDevInfos, DbDevExportInfos, DbDevImportInfos, DbHistoryList, \
     DeviceDataHistoryList, StdGroupReplyVector, \
@@ -42,8 +41,8 @@ from _PyTango import (StdStringVector, StdLongVector, StdDoubleVector, \
     DevCommandInfo, CommandInfo, DataReadyEventData, DeviceInfo, \
     LockerInfo, PollDevice, TimeVal)
 
-from utils import document_method
-from utils import document_enum as __document_enum
+from .utils import document_method, is_integer
+from .utils import document_enum as __document_enum
 
 def __StdVector__add(self, seq):
     ret = seq.__class__(self)
@@ -52,18 +51,18 @@ def __StdVector__add(self, seq):
 
 def __StdVector__mul(self, n):
     ret = self.__class__()
-    for _ in xrange(n):
+    for _ in range(n):
         ret.extend(self)
     return ret
 
 def __StdVector__imul(self, n):
     ret = self.__class__()
-    for _ in xrange(n):
+    for _ in range(n):
         ret.extend(self)
     return ret
 
 def __StdVector__getitem(self, key):
-    if operator.isNumberType(key) or key.step is None:
+    if is_integer(key) or key.step is None:
         return self.__original_getitem(key)
     
     res = self.__class__()
@@ -75,7 +74,7 @@ def __StdVector__getitem(self, key):
     if stop > nb:
         stop = nb
     
-    for i in xrange(start, stop, key.step or 1):
+    for i in range(start, stop, key.step or 1):
         res.append(self[i])
     
     return res
@@ -124,11 +123,6 @@ def __doc_base_types():
           of lists
         - String   : The data will be stored 'as is', the binary data
           as it comes from TangoC++ in 'value'.
-        - PyTango3 : Backward compatibility mode. If the attribute is
-          an scalar, value and w_scalar_value will contain a value.
-          If it's an SPECTRUM or IMAGE it will be exported as a flat
-          list in value, were both the read and the write part are
-          in value.
         - Nothing  : The value will not be extracted from DeviceAttribute
     """ )
     
@@ -664,7 +658,7 @@ def __doc_base_types():
         - tv_usec : microseconds
         - tv_nsec : nanoseconds"""
 
-def init(doc=True):
+def base_types_init(doc=True):
     __init_base_types()
     if doc:
-        __doc_base_types()
\ No newline at end of file
+        __doc_base_types()
diff --git a/PyTango/callback.py b/PyTango/callback.py
index 275e2e4..6b78bb4 100644
--- a/PyTango/callback.py
+++ b/PyTango/callback.py
@@ -25,11 +25,11 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["callback_init"]
 
 __docformat__ = "restructuredtext"
 
-from _PyTango import CmdDoneEvent, AttrReadEvent, AttrWrittenEvent
+from ._PyTango import CmdDoneEvent, AttrReadEvent, AttrWrittenEvent
 
 def __init_Callback():
     pass
@@ -74,7 +74,7 @@ def __doc_Callback():
             - ext        :
     """
 
-def init(doc=True):
+def callback_init(doc=True):
     __init_Callback()
     if doc:
         __doc_Callback()
diff --git a/PyTango/connection.py b/PyTango/connection.py
index 85a06cc..7211b53 100644
--- a/PyTango/connection.py
+++ b/PyTango/connection.py
@@ -25,17 +25,19 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["connection_init"]
 
 __docformat__ = "restructuredtext"
 
-from _PyTango import Connection, DeviceData, __CallBackAutoDie, CmdArgType
-from _PyTango import DeviceProxy, Database
-from _PyTango import ExtractAs
-from utils import document_method as __document_method
-from utils import document_static_method as __document_static_method
 import operator
 
+from ._PyTango import Connection, DeviceData, __CallBackAutoDie, CmdArgType, \
+    DeviceProxy, Database, ExtractAs
+from .utils import document_method as __document_method
+from .utils import document_static_method as __document_static_method
+import collections
+
+
 def __CallBackAutoDie__cmd_ended_aux(self, fn):
     def __new_fn(cmd_done_event):
         try:
@@ -67,7 +69,7 @@ def __get_command_inout_param(self, cmd_name, cmd_param=None):
         if isinstance(cmd_param, str):
             param.insert(CmdArgType.DevString, cmd_param)
             return param
-        elif operator.isSequenceType(cmd_param) and all([isinstance(x,str) for x in cmd_param]):
+        elif isinstance(cmd_param, collections.Sequence) and all([isinstance(x,str) for x in cmd_param]):
             param.insert(CmdArgType.DevVarStringArray, cmd_param)
             return param
         else:
@@ -165,7 +167,7 @@ def __Connection__command_inout_asynch(self, cmd_name, *args):
         forget = False
         return self.__command_inout_asynch_id(cmd_name, argin, forget)
     elif len(args) == 1:
-        if callable(args[0]): # command_inout_asynch(lambda)
+        if isinstance(args[0], collections.Callable): # command_inout_asynch(lambda)
             cb = __CallBackAutoDie()
             cb.cmd_ended = __CallBackAutoDie__cmd_ended_aux(self, args[0])
             argin = __get_command_inout_param(self, cmd_name)
@@ -180,7 +182,7 @@ def __Connection__command_inout_asynch(self, cmd_name, *args):
             forget = False
             return self.__command_inout_asynch_id(cmd_name, argin, forget)
     elif len(args) == 2:
-        if callable(args[1]): #command_inout_asynch( value, lambda)
+        if isinstance(args[1], collections.Callable): #command_inout_asynch( value, lambda)
             cb = __CallBackAutoDie()
             cb.cmd_ended = __CallBackAutoDie__cmd_ended_aux(self, args[1])
             argin = __get_command_inout_param(self, cmd_name, args[0])
@@ -545,7 +547,18 @@ def __doc_Connection():
 
         New in PyTango 7.0.0
     """)
+
+    document_method("get_access_right", """
+    get_access_right(self) -> AccessControlType
     
+            Returns the current access control type
+            
+        Parameters : None
+        Return     : (AccessControlType) The current access control type
+
+        New in PyTango 8.0.0
+    """)
+
     document_static_method("get_fqdn", """
     get_fqdn(self) -> str
     
@@ -590,7 +603,7 @@ def __doc_Connection():
         New in PyTango 7.2.0
     """)
     
-def init(doc=True):
+def connection_init(doc=True):
     __init_Connection()
     if doc:
         __doc_Connection()
diff --git a/PyTango/db.py b/PyTango/db.py
index 38a2677..7611e1a 100644
--- a/PyTango/db.py
+++ b/PyTango/db.py
@@ -25,26 +25,18 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["db_init"]
 
 __docformat__ = "restructuredtext"
 
-import types
-import operator
+from ._PyTango import StdStringVector, Database, DbDatum, DbData, \
+    DbDevInfo, DbDevInfos, DbDevImportInfo, DbDevExportInfo, DbDevExportInfos, \
+    DbHistory, DbServerInfo
 
-from _PyTango import StdStringVector
-from _PyTango import Database, DbDatum, DbData
-from _PyTango import DbDevInfo, DbDevInfos
-from _PyTango import DbDevImportInfo, DbDevExportInfo
-from _PyTango import DbDevExportInfos
-from _PyTango import DbHistory, DbServerInfo
-
-from utils import seq_2_StdStringVector
-from utils import seq_2_DbDevInfos
-from utils import seq_2_DbDevExportInfos
-from utils import seq_2_DbData
-from utils import DbData_2_dict
-from utils import document_method as __document_method
+from .utils import is_pure_str, is_non_str_seq, seq_2_StdStringVector, \
+    seq_2_DbDevInfos, seq_2_DbDevExportInfos, seq_2_DbData, DbData_2_dict
+from .utils import document_method as __document_method
+import collections
 
 #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
 # DbDatum extension
@@ -99,7 +91,7 @@ def __Database__add_server(self, servname, dev_info):
             Throws     : ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError)
     """
 
-    if not operator.isSequenceType(dev_info) and \
+    if not isinstance(dev_info, collections.Sequence) and \
        not isinstance(dev_info, DbDevInfo):
         raise TypeError('value must be a DbDevInfos, a seq<DbDevInfo> or ' \
                         'a DbDevInfo')
@@ -126,7 +118,7 @@ def __Database__export_server(self, dev_info):
             Throws     : ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError)
     """
 
-    if not operator.isSequenceType(dev_info) and \
+    if not isinstance(dev_info, collections.Sequence) and \
        not isinstance(dev_info, DbDevExportInfo):
         raise TypeError('value must be a DbDevExportInfos, a seq<DbDevExportInfo> or ' \
                         'a DbDevExportInfo')
@@ -147,19 +139,19 @@ def __Database__generic_get_property(self, obj_name, value, f):
     elif isinstance(value, DbDatum):
         new_value = DbData()
         new_value.append(value)
-    elif type(value) in types.StringTypes:
+    elif is_pure_str(value):
         new_value = DbData()
         new_value.append(DbDatum(value))
-    elif operator.isSequenceType(value):
+    elif isinstance(value, collections.Sequence):
         new_value = DbData()
         for e in value:
             if isinstance(e, DbDatum):
                 new_value.append(e)
             else:
                 new_value.append(DbDatum(str(e)))
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k, v in value.iteritems():
+        for k, v in value.items():
             if isinstance(v, DbDatum):
                 new_value.append(v)
             else:
@@ -181,16 +173,16 @@ def __Database__generic_put_property(self, obj_name, value, f):
         new_value = DbData()
         new_value.append(value)
         value = new_value
-    elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+    elif is_non_str_seq(value):
         new_value = seq_2_DbData(value)
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k, v in value.iteritems():
+        for k, v in value.items():
             if isinstance(v, DbDatum):
                 new_value.append(v)
                 continue
             db_datum = DbDatum(k)
-            if operator.isSequenceType(v) and not type(v) in types.StringTypes:
+            if is_non_str_seq(v):
                 seq_2_StdStringVector(v, db_datum.value_string)
             else:
                 db_datum.value_string.append(str(v))
@@ -208,19 +200,19 @@ def __Database__generic_delete_property(self, obj_name, value, f):
     elif isinstance(value, DbDatum):
         new_value = DbData()
         new_value.append(value)
-    elif type(value) in types.StringTypes:
+    elif is_pure_str(value):
         new_value = DbData()
         new_value.append(DbDatum(value))
-    elif operator.isSequenceType(value):
+    elif isinstance(value, collections.Sequence):
         new_value = DbData()
         for e in value:
             if isinstance(e, DbDatum):
                 new_value.append(e)
             else:
                 new_value.append(DbDatum(str(e)))
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k, v in value.iteritems():
+        for k, v in value.items():
             if isinstance(v, DbDatum):
                 new_value.append(v)
             else:
@@ -407,7 +399,7 @@ def __Database__get_device_property_list(self, dev_name, wildcard, array=None):
         return self._get_device_property_list(dev_name, wildcard)
     elif isinstance(array, StdStringVector):
         return self._get_device_property_list(dev_name, wildcard, array)
-    elif operator.isSequenceType(array) and not type(array) in types.StringTypes:
+    elif is_non_str_seq(array):
         res = self._get_device_property_list(dev_name, wildcard)
         for e in res: array.append(e)
         return array
@@ -448,19 +440,19 @@ def __Database__get_device_attribute_property(self, dev_name, value):
     elif isinstance(value, DbDatum):
         new_value = DbData()
         new_value.append(value)
-    elif type(value) in types.StringTypes:
+    elif is_pure_str(value):
         new_value = DbData()
         new_value.append(DbDatum(value))
-    elif operator.isSequenceType(value):
+    elif isinstance(value, collections.Sequence):
         new_value = DbData()
         for e in value:
             if isinstance(e, DbDatum):
                 new_value.append(e)
             else:
                 new_value.append(DbDatum(str(e)))
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k, v in value.iteritems():
+        for k, v in value.items():
             if isinstance(v, DbDatum):
                 new_value.append(v)
             else:
@@ -481,7 +473,7 @@ def __Database__get_device_attribute_property(self, dev_name, value):
         ret[db_datum.name] = curr_dict
         nb_props = int(db_datum[0])
         i += 1
-        for k in xrange(nb_props):
+        for k in range(nb_props):
             db_datum = new_value[i]
             curr_dict[db_datum.name] = db_datum.value_string
             i += 1
@@ -512,20 +504,20 @@ def __Database__put_device_attribute_property(self, dev_name, value):
             Throws     : ConnectionFailed, CommunicationFailed, DevFailed from device (DB_SQLError)"""
     if isinstance(value, DbData):
         pass
-    elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+    elif is_non_str_seq(value):
         new_value = seq_2_DbData(value)
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k1, v1 in value.iteritems():
+        for k1, v1 in value.items():
             attr = DbDatum(k1)
             attr.append(str(len(v1)))
             new_value.append(attr)
-            for k2, v2 in v1.iteritems():
+            for k2, v2 in v1.items():
                 if isinstance(v2, DbDatum):
                     new_value.append(v2)
                     continue
                 db_datum = DbDatum(k2)
-                if operator.isSequenceType(v2) and not type(v2) in types.StringTypes:
+                if is_non_str_seq(v2):
                     seq_2_StdStringVector(v2, db_datum.value_string)
                 else:
                     db_datum.value_string.append(str(v2))
@@ -556,11 +548,11 @@ def __Database__delete_device_attribute_property(self, dev_name, value):
 
     if isinstance(value, DbData):
         new_value = value
-    elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+    elif is_non_str_seq(value):
         new_value = seq_2_DbData(value)
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k1, v1 in value.iteritems():
+        for k1, v1 in value.items():
             attr = DbDatum(k1)
             attr.append(str(len(v1)))
             new_value.append(attr)
@@ -681,19 +673,19 @@ def __Database__get_class_attribute_property(self, class_name, value):
     elif isinstance(value, DbDatum):
         new_value = DbData()
         new_value.append(value)
-    elif type(value) in types.StringTypes:
+    elif is_pure_str(value):
         new_value = DbData()
         new_value.append(DbDatum(value))
-    elif operator.isSequenceType(value):
+    elif isinstance(value, collections.Sequence):
         new_value = DbData()
         for e in value:
             if isinstance(e, DbDatum):
                 new_value.append(e)
             else:
                 new_value.append(DbDatum(str(e)))
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k, v in value.iteritems():
+        for k, v in value.items():
             if isinstance(v, DbDatum):
                 new_value.append(v)
             else:
@@ -714,7 +706,7 @@ def __Database__get_class_attribute_property(self, class_name, value):
         ret[db_datum.name] = curr_dict
         nb_props = int(db_datum[0])
         i += 1
-        for k in xrange(nb_props):
+        for k in range(nb_props):
             db_datum = new_value[i]
             curr_dict[db_datum.name] = db_datum.value_string
             i += 1
@@ -746,20 +738,20 @@ def __Database__put_class_attribute_property(self, class_name, value):
 
     if isinstance(value, DbData):
         pass
-    elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+    elif is_non_str_seq(value):
         new_value = seq_2_DbData(value)
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k1, v1 in value.iteritems():
+        for k1, v1 in value.items():
             attr = DbDatum(k1)
             attr.append(str(len(v1)))
             new_value.append(attr)
-            for k2, v2 in v1.iteritems():
+            for k2, v2 in v1.items():
                 if isinstance(v2, DbDatum):
                     new_value.append(v2)
                     continue
                 db_datum = DbDatum(k2)
-                if operator.isSequenceType(v2) and not type(v2) in types.StringTypes:
+                if is_non_str_seq(v2):
                     seq_2_StdStringVector(v2, db_datum.value_string)
                 else:
                     db_datum.value_string.append(str(v2))
@@ -793,11 +785,11 @@ def __Database__delete_class_attribute_property(self, class_name, value):
 
     if isinstance(value, DbData):
         new_value = value
-    elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+    elif is_non_str_seq(value):
         new_value = seq_2_DbData(value)
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k1, v1 in value.iteritems():
+        for k1, v1 in value.items():
             attr = DbDatum(k1)
             attr.append(str(len(v1)))
             new_value.append(attr)
@@ -1075,10 +1067,10 @@ def __doc_Database():
 
             Example :
                 dev_imp_info = db.import_device('my/own/device')
-                print dev_imp_info.name
-                print dev_imp_info.exported
-                print dev_imp_info.ior
-                print dev_imp_info.version
+                print(dev_imp_info.name)
+                print(dev_imp_info.exported)
+                print(dev_imp_info.ior)
+                print(dev_imp_info.version)
 
         Parameters :
             - dev_name : (str) device name
@@ -2089,7 +2081,7 @@ def __doc_DbServerInfo():
         - mode : (str) mode
         - level : (str) level"""
 
-def init(doc=True):
+def db_init(doc=True):
     __init_DbDatum()
     if doc:
         __doc_DbDatum()
diff --git a/PyTango/device_attribute.py b/PyTango/device_attribute.py
index 97ae59f..4859359 100644
--- a/PyTango/device_attribute.py
+++ b/PyTango/device_attribute.py
@@ -25,14 +25,14 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["device_attribute_init"]
 
 __docformat__ = "restructuredtext"
 
 import copy
 
-from utils import document_method as __document_method
-from _PyTango import DeviceAttribute, ExtractAs
+from .utils import document_method as __document_method
+from ._PyTango import DeviceAttribute, ExtractAs
 
 def __DeviceAttribute__get_data(self):
     return self.get_data_raw().extract()
@@ -108,12 +108,38 @@ def __doc_DeviceAttribute():
         Return     : (sequence<DevError>)
     """ )
 
+    document_method("set_w_dim_x", """
+    set_w_dim_x(self, val) -> None
+
+            Sets the write value dim x.
+
+        Parameters : 
+            - val : (int) new write dim x
+            
+        Return     : None
+        
+        New in PyTango 8.0.0
+    """ )
+
+    document_method("set_w_dim_y", """
+    set_w_dim_y(self, val) -> None
+
+            Sets the write value dim y.
+
+        Parameters : 
+            - val : (int) new write dim y
+            
+        Return     : None
+        
+        New in PyTango 8.0.0
+    """ )
+    
 def __init_DeviceAttribute():
     DeviceAttribute.__init_orig = DeviceAttribute.__init__
     DeviceAttribute.__init__ = __DeviceAttribute__init
     DeviceAttribute.ExtractAs = ExtractAs
 
-def init(doc=True):
+def device_attribute_init(doc=True):
     __init_DeviceAttribute()
     if doc:
         __doc_DeviceAttribute()
diff --git a/PyTango/device_class.py b/PyTango/device_class.py
index fd878b9..5af4f56 100644
--- a/PyTango/device_class.py
+++ b/PyTango/device_class.py
@@ -25,26 +25,26 @@
 This is an internal PyTango module.
 """
 
-__all__ = [ "DeviceClass" ]
+from __future__ import print_function
+
+__all__ = [ "DeviceClass", "device_class_init" ]
 
 __docformat__ = "restructuredtext"
 
-import types
-import operator
+import collections
 
-from _PyTango import Except, DevFailed
-from _PyTango import _DeviceClass, Database
-from _PyTango import CmdArgType, DispLevel
-from _PyTango import UserDefaultAttrProp
+from ._PyTango import Except, DevFailed, _DeviceClass, CmdArgType, \
+    DispLevel, UserDefaultAttrProp
+from .pyutil import Util
 
-from pyutil import Util
+from .utils import is_pure_str, is_non_str_seq, seqStr_2_obj, obj_2_str, \
+    is_array
+from .utils import document_method as __document_method
 
-from utils import seqStr_2_obj, obj_2_str, is_array
-from utils import document_method as __document_method
+from .globals import get_class, get_class_by_class, \
+    get_constructed_class_by_class
+from .attr_data import AttrData
 
-from globals import get_class, get_class_by_class
-from globals import get_constructed_class_by_class
-from attr_data import AttrData
 
 class PropUtil:
     """An internal Property util class"""
@@ -67,7 +67,7 @@ class PropUtil:
     def __init__(self):
         self.db = None
         if Util._UseDb:
-            self.db = Database()
+            self.db = Util.instance().get_database()
 
     def set_default_property_values(self, dev_class, class_prop, dev_prop):
         """
@@ -82,14 +82,14 @@ class PropUtil:
 
             Return     : None
         """
-        for name in class_prop.keys():
+        for name in class_prop:
             type = self.get_property_type(name, class_prop)
             val  = self.get_property_values(name, class_prop)
             val  = self.values2string(val, type)
             desc = self.get_property_description(name, class_prop)
             dev_class.add_wiz_class_prop(name, desc, val)
 
-        for name in dev_prop.keys():
+        for name in dev_prop:
             type = self.get_property_type(name, dev_prop)
             val  = self.get_property_values(name, dev_prop)
             val  = self.values2string(val, type)
@@ -113,16 +113,16 @@ class PropUtil:
             return
 
         # call database to get properties
-        props = self.db.get_class_property(dev_class.get_name(), class_prop.keys())
+        props = self.db.get_class_property(dev_class.get_name(), list(class_prop.keys()))
 
         # if value defined in database, store it
-        for name in class_prop.keys():
+        for name in class_prop:
             if props[name]:
                 type   = self.get_property_type(name, class_prop)
                 values = self.stringArray2values(props[name], type)
                 self.set_property_values(name, class_prop, values)
             else:
-                print name, " property NOT found in database"
+                print(name + " property NOT found in database")
 
     def get_device_properties(self, dev, class_prop, dev_prop):
         """
@@ -141,9 +141,9 @@ class PropUtil:
             return
 
         #    Call database to get properties
-        props = self.db.get_device_property(dev.get_name(),dev_prop.keys())
+        props = self.db.get_device_property(dev.get_name(), list(dev_prop.keys()))
         #    if value defined in database, store it
-        for name in dev_prop.keys():
+        for name in dev_prop:
             prop_value = props[name]
             if len(prop_value):
                 data_type = self.get_property_type(name, dev_prop)
@@ -181,7 +181,7 @@ class PropUtil:
                     - v : (object) the object to be analysed
 
                 Return     : (bool) True if the object is a sequence or False otherwise"""
-        return operator.isSequenceType(v)
+        return isinstance(v, collections.Sequence)
 
     def is_empty_seq(self, v):
         """
@@ -244,10 +244,10 @@ class PropUtil:
         except:
             val = []
 
-        if is_array(tg_type) or (operator.isSequenceType(val) and not len(val)):
+        if is_array(tg_type) or (isinstance(val, collections.Sequence) and not len(val)):
             return val
         else:
-            if operator.isSequenceType(val) and not type(val) in types.StringTypes:
+            if is_non_str_seq(val):
                 return val[0]
             else:
                 return val
@@ -292,12 +292,14 @@ class DeviceClass(_DeviceClass):
             pu.set_default_property_values(self, self.class_property_list,
                                            self.device_property_list)
             pu.get_class_properties(self, self.class_property_list)
-            for prop_name in self.class_property_list.keys():
-                setattr(self, prop_name, pu.get_property_values(prop_name, self.class_property_list))
-        except DevFailed, df:
+            for prop_name in self.class_property_list:
+                if not hasattr(self, prop_name):
+                    setattr(self, prop_name, pu.get_property_values(prop_name,
+                            self.class_property_list))
+        except DevFailed as df:
             print("PyDS: %s: A Tango error occured in the constructor:" % name)
             Except.print_exception(df)
-        except Exception, e:
+        except Exception as e:
             print("PyDS: %s: An error occured in the constructor:" % name)
             print(str(e))
             
@@ -318,7 +320,7 @@ class DeviceClass(_DeviceClass):
     def __attribute_factory(self, attr_list):
         """for internal usage only"""
 
-        for attr_name, attr_info in self.attr_list.iteritems():
+        for attr_name, attr_info in self.attr_list.items():
             attr_data = AttrData(attr_name, self.get_name(), attr_info)
             self.__create_attribute(attr_list, attr_data)
 
@@ -337,7 +339,7 @@ class DeviceClass(_DeviceClass):
     def __create_user_default_attr_prop(self, attr_name, extra_info):
         """for internal usage only"""
         p = UserDefaultAttrProp()
-        for k, v in extra_info.iteritems():
+        for k, v in extra_info.items():
             k_lower = k.lower()
             method_name = "set_%s" % k_lower.replace(' ','_')
             if hasattr(p, method_name):
@@ -364,7 +366,7 @@ class DeviceClass(_DeviceClass):
                   "The init_device() method does not exist!" % name
             Except.throw_exception("PyDs_WrongCommandDefinition", msg, "command_factory()")
 
-        for cmd_name, cmd_info in self.cmd_list.iteritems():
+        for cmd_name, cmd_info in self.cmd_list.items():
             self.__create_command(deviceimpl_class, cmd_name, cmd_info)
 
     def __create_command(self, deviceimpl_class, cmd_name, cmd_info):
@@ -374,7 +376,7 @@ class DeviceClass(_DeviceClass):
         # check for well defined command info
 
         # check parameter
-        if not operator.isSequenceType(cmd_info):
+        if not isinstance(cmd_info, collections.Sequence):
             msg = "Wrong data type for value for describing command %s in " \
                   "class %s\nMust be a sequence with 2 or 3 elements" % (cmd_name, name)
             self.__throw_create_command_exception(msg)
@@ -386,7 +388,7 @@ class DeviceClass(_DeviceClass):
 
         param_info, result_info = cmd_info[0], cmd_info[1]
 
-        if not operator.isSequenceType(param_info):
+        if not isinstance(param_info, collections.Sequence):
             msg = "Wrong data type in command argument for command %s in " \
                   "class %s\nCommand parameter (first element) must be a sequence" % (cmd_name, name)
             self.__throw_create_command_exception(msg)
@@ -409,14 +411,14 @@ class DeviceClass(_DeviceClass):
         param_desc = ""
         if len(param_info) > 1:
             param_desc = param_info[1]
-            if not type(param_desc) in types.StringTypes:
+            if not is_pure_str(param_desc):
                 msg = "Wrong data type in command parameter for command %s in " \
                       "class %s\nCommand parameter description (second element " \
                       "in first sequence), when given, must be a string"
                 self.__throw_create_command_exception(msg)
 
         # Check result
-        if not operator.isSequenceType(result_info):
+        if not isinstance(result_info, collections.Sequence):
             msg = "Wrong data type in command result for command %s in " \
                   "class %s\nCommand result (second element) must be a sequence" % (cmd_name, name)
             self.__throw_create_command_exception(msg)
@@ -439,7 +441,7 @@ class DeviceClass(_DeviceClass):
         result_desc = ""
         if len(result_info) > 1:
             result_desc = result_info[1]
-            if not type(result_desc) in types.StringTypes:
+            if not is_pure_str(result_desc):
                 msg = "Wrong data type in command result for command %s in " \
                       "class %s\nCommand parameter description (second element " \
                       "in second sequence), when given, must be a string" % (cmd_name, name)
@@ -450,7 +452,7 @@ class DeviceClass(_DeviceClass):
 
         if len(cmd_info) == 3:
             extra_info = cmd_info[2]
-            if not operator.isMappingType(extra_info):
+            if not isinstance(extra_info, collections.Mapping):
                 msg = "Wrong data type in command information for command %s in " \
                       "class %s\nCommand information (third element in sequence), " \
                       "when given, must be a dictionary" % (cmd_name, name)
@@ -462,7 +464,7 @@ class DeviceClass(_DeviceClass):
                       "three elements" % (cmd_name, name)
                 self.__throw_create_command_exception(msg)
 
-            for info_name, info_value in extra_info.iteritems():
+            for info_name, info_value in extra_info.items():
                 info_name_lower = info_name.lower()
                 if info_name_lower == "display level":
                     try:
@@ -473,7 +475,7 @@ class DeviceClass(_DeviceClass):
                               "PyTango.DispLevel" % (cmd_name, name)
                         self.__throw_create_command_exception(msg)
                 elif info_name_lower == "default command":
-                    if not type(info_value) in types.StringTypes:
+                    if not is_pure_str(info_value):
                         msg = "Wrong data type in command information for command %s in " \
                               "class %s\nCommand information for default command is not a " \
                               "string" % (cmd_name, name)
@@ -497,7 +499,7 @@ class DeviceClass(_DeviceClass):
         # check that the method to be executed exists
         try:
             cmd = getattr(deviceimpl_class, cmd_name)
-            if not callable(cmd):
+            if not isinstance(cmd, collections.Callable):
                 msg = "Wrong definition of command %s in " \
                       "class %s\nThe object exists in class but is not " \
                       "a method!" % (cmd_name, name)
@@ -510,7 +512,7 @@ class DeviceClass(_DeviceClass):
         is_allowed_name = "is_%s_allowed" % cmd_name
         try:
             is_allowed = getattr(deviceimpl_class, is_allowed_name)
-            if not callable(is_allowed):
+            if not isinstance(is_allowed, collections.Callable):
                 msg = "Wrong definition of command %s in " \
                       "class %s\nThe object '%s' exists in class but is " \
                       "not a method!" % (cmd_name, name, is_allowed_name)
@@ -783,6 +785,29 @@ def __doc_DeviceClass():
         Parameters : None
         Return     : (sequence<PyTango.DeviceImpl>) list of PyTango.DeviceImpl objects for this class
     """ )
+
+    document_method("get_command_list", """
+    get_command_list(self) -> sequence<PyTango.Command>
+
+            Gets the list of PyTango.Command objects for this class
+
+        Parameters : None
+        Return     : (sequence<PyTango.Command>) list of PyTango.Command objects for this class
+        
+        New in PyTango 8.0.0
+    """ )
+
+    document_method("get_cmd_by_name", """
+    get_cmd_by_name(self, (str)cmd_name) -> PyTango.Command
+
+            Get a reference to a command object.
+
+        Parameters :
+            - cmd_name : (str) command name
+        Return     : (PyTango.Command) PyTango.Command object
+        
+        New in PyTango 8.0.0
+    """ )
     
     document_method("add_wiz_dev_prop", """
     add_wiz_dev_prop(self, str, str) -> None
@@ -804,7 +829,7 @@ def __doc_DeviceClass():
         Return     : None
     """ )
 
-def init(doc=True):
+def device_class_init(doc=True):
     __init_DeviceClass()
     if doc:
         __doc_DeviceClass()
diff --git a/PyTango/device_data.py b/PyTango/device_data.py
index 4a7b608..edfed89 100644
--- a/PyTango/device_data.py
+++ b/PyTango/device_data.py
@@ -25,12 +25,12 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["device_data_init"]
 
 __docformat__ = "restructuredtext"
 
-from utils import document_method as __document_method
-from _PyTango import DeviceData
+from .utils import document_method as __document_method
+from ._PyTango import DeviceData
 
 def __DeviceData__get_data(self):
     return self.get_data_raw().extract()
@@ -89,7 +89,7 @@ def __doc_DeviceData():
         Return     : The content arg type.
     """ )
 
-def init(doc=True):
+def device_data_init(doc=True):
     __init_DeviceData()
     if doc:
         __doc_DeviceData()
diff --git a/PyTango/device_proxy.py b/PyTango/device_proxy.py
index 661f365..24db823 100644
--- a/PyTango/device_proxy.py
+++ b/PyTango/device_proxy.py
@@ -27,25 +27,31 @@ This is an internal PyTango module.
 
 from __future__ import with_statement
 
-__all__ = []
+__all__ = ["device_proxy_init"]
 
 __docformat__ = "restructuredtext"
 
-import operator
-import types
 import threading
 
-from _PyTango import StdStringVector
-from _PyTango import DbData, DbDatum
-from _PyTango import AttributeInfo, AttributeInfoEx
-from _PyTango import AttributeInfoList, AttributeInfoListEx
-from _PyTango import DeviceProxy
-from _PyTango import __CallBackAutoDie, __CallBackPushEvent, EventType
-from _PyTango import DevFailed, Except
-from _PyTango import ExtractAs
-from PyTango.utils import seq_2_StdStringVector, StdStringVector_2_seq
-from PyTango.utils import seq_2_DbData, DbData_2_dict
-from utils import document_method as __document_method
+from ._PyTango import StdStringVector, DbData, DbDatum, AttributeInfo, \
+    AttributeInfoEx, AttributeInfoList, AttributeInfoListEx, DeviceProxy, \
+    __CallBackAutoDie, __CallBackPushEvent, EventType, DevFailed, Except, \
+    ExtractAs
+from .utils import is_pure_str, is_non_str_seq, is_integer, \
+    seq_2_StdStringVector, StdStringVector_2_seq, seq_2_DbData, DbData_2_dict
+from .utils import document_method as __document_method
+import collections
+import numbers
+
+class __TangoInfo(object):
+    """Helper class for when DeviceProxy.info() is not available"""
+    
+    def __init__(self):
+        self.dev_class = self.dev_type = 'Device'
+        self.doc_url = 'http://www.esrf.fr/computing/cs/tango/tango_doc/ds_doc/'
+        self.server_host = 'Unknown'
+        self.server_id = 'Unknown'
+        self.server_version = 1
 
 #-------------------------------------------------------------------------------
 # Pythonic API: transform tango commands into methods and tango attributes into
@@ -74,7 +80,7 @@ def __DeviceProxy__getattr(self, name):
     # ticket http://ipython.scipy.org/ipython/ipython/ticket/229 someday
     # and the ugly trait_names could be removed.
     if name[:2] == "__" or name == 'trait_names':
-        raise AttributeError, name
+        raise AttributeError(name)
     
     name_l = name.lower()
     cmd_info = None
@@ -107,7 +113,7 @@ def __DeviceProxy__getattr(self, name):
             find_attr = False
     
     if not find_attr or name_l not in self.__attr_cache:
-        raise AttributeError, name
+        raise AttributeError(name)
     
     return self.read_attribute(name).value
 
@@ -130,7 +136,7 @@ def __DeviceProxy__getAttributeNames(self):
     try:
         lst = [cmd.cmd_name for cmd in self.command_list_query()]
         lst += self.get_attribute_list()
-        lst += map(str.lower, lst)
+        lst += list(map(str.lower, lst))
         lst.sort()
         return lst
     except Exception:
@@ -185,7 +191,7 @@ def __DeviceProxy__read_attributes_asynch(self, attr_names, cb=None, extract_as=
         return self.__read_attributes_asynch(attr_names)
 
     cb2 = __CallBackAutoDie()
-    if callable(cb):
+    if isinstance(cb, collections.Callable):
         cb2.attr_read = cb
     else:
         cb2.attr_read = cb.attr_read
@@ -247,7 +253,7 @@ def __DeviceProxy__write_attributes_asynch(self, attr_values, cb=None):
         return self.__write_attributes_asynch(attr_values)
 
     cb2 = __CallBackAutoDie()
-    if callable(cb):
+    if isinstance(cb, collections.Callable):
         cb2.attr_write = cb
     else:
         cb2.attr_write = cb.attr_write
@@ -300,7 +306,7 @@ def __DeviceProxy__get_property(self, propname, value=None):
                      DevFailed from database device
     """
 
-    if type(propname) in types.StringTypes or isinstance(propname, StdStringVector):
+    if is_pure_str(propname) or isinstance(propname, StdStringVector):
         new_value = value
         if new_value is None:
             new_value = DbData()
@@ -311,12 +317,12 @@ def __DeviceProxy__get_property(self, propname, value=None):
         new_value.append(propname)
         self._get_property(new_value)
         return DbData_2_dict(new_value)
-    elif operator.isSequenceType(propname):
+    elif isinstance(propname, collections.Sequence):
         if isinstance(propname, DbData):
             self._get_property(propname)
             return DbData_2_dict(propname)
 
-        if type(propname[0]) in types.StringTypes:
+        if is_pure_str(propname[0]):
             new_propname = StdStringVector()
             for i in propname: new_propname.append(i)
             new_value = value
@@ -363,16 +369,16 @@ def __DeviceProxy__put_property(self, value):
         new_value = DbData()
         new_value.append(value)
         value = new_value
-    elif operator.isSequenceType(value) and not type(value) in types.StringTypes:
+    elif is_non_str_seq(value):
         new_value = seq_2_DbData(value)
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k, v in value.iteritems():
+        for k, v in value.items():
             if isinstance(v, DbDatum):
                 new_value.append(v)
                 continue
             db_datum = DbDatum(k)
-            if operator.isSequenceType(v) and not type(v) in types.StringTypes:
+            if is_non_str_seq(v):
                 seq_2_StdStringVector(v, db_datum.value_string)
             else:
                 db_datum.value_string.append(str(v))
@@ -415,21 +421,21 @@ def __DeviceProxy__delete_property(self, value):
                     DevFailed from device (DB_SQLError)
     """
     if isinstance(value, DbData) or isinstance(value, StdStringVector) or \
-       type(value) in types.StringTypes:
+       is_pure_str(value):
         new_value = value
     elif isinstance(value, DbDatum):
         new_value = DbData()
         new_value.append(value)
-    elif operator.isSequenceType(value):
+    elif isinstance(value, collections.Sequence):
         new_value = DbData()
         for e in value:
             if isinstance(e, DbDatum):
                 new_value.append(e)
             else:
                 new_value.append(DbDatum(str(e)))
-    elif operator.isMappingType(value):
+    elif isinstance(value, collections.Mapping):
         new_value = DbData()
-        for k, v in value.iteritems():
+        for k, v in value.items():
             if isinstance(v, DbDatum):
                 new_value.append(v)
             else:
@@ -474,7 +480,7 @@ def __DeviceProxy__get_property_list(self, filter, array=None):
     if isinstance(array, StdStringVector):
         self._get_property_list(filter, array)
         return array
-    elif operator.isSequenceType(array):
+    elif isinstance(array, collections.Sequence):
         new_array = StdStringVector()
         self._get_property_list(filter, new_array)
         StdStringVector_2_seq(new_array, array)
@@ -513,9 +519,9 @@ def __DeviceProxy__get_attribute_config(self, value):
 
         Deprecated: use get_attribute_config_ex instead
     """
-    if isinstance(value, StdStringVector) or type(value) in types.StringTypes:
+    if isinstance(value, StdStringVector) or is_pure_str(value):
         return self._get_attribute_config(value)
-    elif operator.isSequenceType(value):
+    elif isinstance(value, collections.Sequence):
         v = seq_2_StdStringVector(value)
         return self._get_attribute_config(v)
 
@@ -551,11 +557,11 @@ def __DeviceProxy__get_attribute_config_ex(self, value):
     """
     if isinstance(value, StdStringVector):
         return self._get_attribute_config_ex(value)
-    elif type(value) in types.StringTypes:
+    elif is_pure_str(value):
         v = StdStringVector()
         v.append(value)
         return self._get_attribute_config_ex(v)
-    elif operator.isSequenceType(value):
+    elif isinstance(value, collections.Sequence):
         v = seq_2_StdStringVector(value)
         return self._get_attribute_config_ex(v)
 
@@ -619,7 +625,7 @@ def __DeviceProxy__set_attribute_config(self, value):
         v = value
     elif isinstance(value, AttributeInfoListEx):
         v = value
-    elif operator.isSequenceType(value):
+    elif isinstance(value, collections.Sequence):
         if not len(value): return
         if isinstance(value[0], AttributeInfoEx):
             v = AttributeInfoListEx()
@@ -718,13 +724,13 @@ def __DeviceProxy__subscribe_event ( self, attr_name, event_type, cb_or_queuesiz
             other subscribe_event() version.
     """
     
-    if callable(cb_or_queuesize):
+    if isinstance(cb_or_queuesize, collections.Callable):
         cb = __CallBackPushEvent()
         cb.push_event = cb_or_queuesize
-    elif hasattr(cb_or_queuesize, "push_event") and callable(cb_or_queuesize.push_event):
+    elif hasattr(cb_or_queuesize, "push_event") and isinstance(cb_or_queuesize.push_event, collections.Callable):
         cb = __CallBackPushEvent()
         cb.push_event = cb_or_queuesize.push_event
-    elif operator.isNumberType(cb_or_queuesize):
+    elif is_integer(cb_or_queuesize):
         cb = cb_or_queuesize # queuesize
     else:
         raise TypeError("Parameter cb_or_queuesize should be a number, a" + \
@@ -770,7 +776,7 @@ def __DeviceProxy__unsubscribe_event(self, event_id):
 def __DeviceProxy__unsubscribe_event_all(self):
     with self.__get_event_map_lock():
         se = self.__get_event_map()
-        event_ids = se.keys()
+        event_ids = list(se.keys())
         se.clear()
     for event_id in event_ids:
         self.__unsubscribe_event(event_id)
@@ -826,25 +832,34 @@ def __DeviceProxy__get_events(self, event_id, callback=None, extract_as=ExtractA
         else:
             assert (False)
             raise ValueError("Unknown event_type: " + str(event_type))
-    elif callable(callback):
+    elif isinstance(callback, collections.Callable):
         cb = __CallBackPushEvent()
         cb.push_event = callback
         return self.__get_callback_events(event_id, cb, extract_as)
-    elif hasattr(callback, 'push_event') and callable(callback.push_event):
+    elif hasattr(callback, 'push_event') and isinstance(callback.push_event, collections.Callable):
         cb = __CallBackPushEvent()
         cb.push_event = callback.push_event
         return self.__get_callback_events(event_id, cb, extract_as)
     else:
         raise TypeError("Parameter 'callback' should be None, a callable object or an object with a 'push_event' method.")
 
-def __DeviceProxy__str(self):
-    if not hasattr(self, '_dev_class'):
+def __DeviceProxy___get_info_(self):
+    """Protected method that gets device info once and stores it in cache"""
+    if not hasattr(self, '_dev_info'):
         try:
-            self.__dict__["_dev_class"] = self.info().dev_class
+            self.__dict__["_dev_info"] = self.info()
         except:
-            return "DeviceProxy(%s)" % self.dev_name()
-    return "%s(%s)" % (self._dev_class, self.dev_name())
-    
+            return __TangoInfo()
+    return self._dev_info
+
+def __DeviceProxy__str(self):
+    info = self._get_info_()
+    return "%s(%s)" % (info.dev_class, self.dev_name())
+
+def __DeviceProxy__str(self):
+    info = self._get_info_()
+    return "%s(%s)" % (info.dev_class, self.dev_name())
+
 def __init_DeviceProxy():
     DeviceProxy.__getattr__ = __DeviceProxy__getattr
     DeviceProxy.__setattr__ = __DeviceProxy__setattr
@@ -882,7 +897,10 @@ def __init_DeviceProxy():
     DeviceProxy.get_events = __DeviceProxy__get_events
     DeviceProxy.__str__ = __DeviceProxy__str
     DeviceProxy.__repr__ = __DeviceProxy__str
+    
+    DeviceProxy._get_info_ = __DeviceProxy___get_info_
 
+    
 def __doc_DeviceProxy():
     def document_method(method_name, desc, append=True):
         return __document_method(DeviceProxy, method_name, desc, append)
@@ -911,12 +929,12 @@ def __doc_DeviceProxy():
         Return     : (DeviceInfo) object
         Example    :
                 dev_info = dev.info()
-                print dev_info.dev_class
-                print dev_info.server_id
-                print dev_info.server_host
-                print dev_info.server_version
-                print dev_info.doc_url
-                print dev_info.dev_type
+                print(dev_info.dev_class)
+                print(dev_info.server_id)
+                print(dev_info.server_host)
+                print(dev_info.server_version)
+                print(dev_info.doc_url)
+                print(dev_info.dev_type)
 
             All DeviceInfo fields are strings except for the server_version
             which is an integer"
@@ -1007,7 +1025,7 @@ def __doc_DeviceProxy():
                      command and from which client computer the command
                      was executed
         Example :
-                print black_box(4)
+                print(black_box(4))
     """ )
 
 #-------------------------------------
@@ -1025,13 +1043,13 @@ def __doc_DeviceProxy():
         Throws     : ConnectionFailed, CommunicationFailed, DevFailed from device
         Example :
                 com_info = dev.command_query(""DevString"")
-                print com_info.cmd_name
-                print com_info.cmd_tag
-                print com_info.in_type
-                print com_info.out_type
-                print com_info.in_type_desc
-                print com_info.out_type_desc
-                print com_info.disp_level
+                print(com_info.cmd_name)
+                print(com_info.cmd_tag)
+                print(com_info.in_type)
+                print(com_info.out_type)
+                print(com_info.in_type_desc)
+                print(com_info.out_type_desc)
+                print(com_info.disp_level)
                 
         See CommandInfo documentation string form more detail
     """ )
@@ -1054,10 +1072,10 @@ def __doc_DeviceProxy():
         Return     : (DbDevImportInfo)
         Example :
                 dev_import = dev.import_info()
-                print dev_import.name
-                print dev_import.exported
-                print dev_ior.ior
-                print dev_version.version
+                print(dev_import.name)
+                print(dev_import.exported)
+                print(dev_ior.ior)
+                print(dev_version.version)
 
         All DbDevImportInfo fields are strings except for exported which
         is an integer"
@@ -1151,6 +1169,14 @@ def __doc_DeviceProxy():
         value was. Since 7.1.4, it returns a **(format<str>, data<buffer>)**
         unless *extract_as* is String, in which case it returns 
         **(format<str>, data<str>)**.
+
+    .. versionchanged:: 8.0.0
+        For DevEncoded attributes, now returns a DeviceAttribute.value
+        as a tuple **(format<str>, data<bytes>)** unless *extract_as* is String,
+        in which case it returns **(format<str>, data<str>)**. Carefull, if
+        using python >= 3 data<str> is decoded using default python 
+        *utf-8* encoding. This means that PyTango assumes tango DS was written
+        encapsulating string into *utf-8* which is the default python enconding.
     """ )
 
     document_method("read_attributes", """
@@ -1775,7 +1801,7 @@ def __doc_DeviceProxy():
         New in PyTango 7.0.0
     """ )
 
-def init(doc=True):
+def device_proxy_init(doc=True):
     __init_DeviceProxy()
     if doc:
         __doc_DeviceProxy()
diff --git a/PyTango/device_server.py b/PyTango/device_server.py
index 1973cc8..0da51b3 100644
--- a/PyTango/device_server.py
+++ b/PyTango/device_server.py
@@ -25,27 +25,27 @@
 This is an internal PyTango module.
 """
 
+from __future__ import print_function
+
 __all__ = [ "ChangeEventProp", "PeriodicEventProp", "ArchiveEventProp",
             "AttributeAlarm", "EventProperties",
-            "AttributeConfig", "AttributeConfig_2", "AttributeConfig_3"]
+            "AttributeConfig", "AttributeConfig_2", "AttributeConfig_3",
+            "MultiAttrProp",
+            "device_server_init"]
 
 __docformat__ = "restructuredtext"
 
 import copy
 
-import _PyTango
-from _PyTango import DeviceImpl, Device_3Impl, Device_4Impl
-from _PyTango import Attribute, WAttribute, MultiAttribute, MultiClassAttribute
-from _PyTango import Attr
-from _PyTango import Logger
-from _PyTango import AttrWriteType, AttrDataFormat, DispLevel
-from _PyTango import UserDefaultAttrProp
+from ._PyTango import DevFailed, DeviceImpl, Device_3Impl, Device_4Impl, \
+    Attribute, WAttribute, MultiAttribute, MultiClassAttribute, \
+    Attr, Logger, AttrWriteType, AttrDataFormat, DispLevel, UserDefaultAttrProp
 
-from utils import document_method as __document_method
-from utils import copy_doc
-from attr_data import AttrData
+from .utils import document_method as __document_method
+from .utils import copy_doc
+from .attr_data import AttrData
 
-import log4tango
+from .log4tango import TangoStream
 
 class AttributeAlarm(object):
     """This class represents the python interface for the Tango IDL object
@@ -96,6 +96,32 @@ class EventProperties(object):
         self.per_event = PeriodicEventProp()
         self.arch_event = ArchiveEventProp()
 
+class MultiAttrProp(object):
+    """This class represents the python interface for the Tango IDL object
+    MultiAttrProp."""
+    
+    def __init__(self):
+        self.label = ''
+        self.description = ''
+        self.unit = ''
+        self.standard_unit = ''
+        self.display_unit = ''
+        self.format = ''
+        self.min_value = ''
+        self.max_value = ''
+        self.min_alarm = ''
+        self.max_alarm = ''
+        self.min_warning = ''
+        self.max_warning = ''
+        self.delta_t = ''
+        self.delta_val = ''
+        self.event_period = ''
+        self.archive_period = ''
+        self.rel_change = ''
+        self.abs_change = ''
+        self.archive_rel_change = ''
+        self.archive_abs_change = ''
+
 def _init_attr_config(attr_cfg):
     """Helper function to initialize attribute config objects"""
     attr_cfg.name = ''
@@ -162,9 +188,12 @@ def __Attribute__get_properties(self, attr_cfg = None):
             New in PyTango 7.1.4
     """
 
-    if attr_cfg is None:
-        attr_cfg = AttributeConfig()
-    return self._get_properties(attr_cfg)
+    if isinstance(attr_cfg,MultiAttrProp):
+        return self._get_properties_multi_attr_prop(attr_cfg)
+    else:
+        if attr_cfg is None:
+            attr_cfg = AttributeConfig()
+        return self._get_properties(attr_cfg)
 
 def __Attribute__get_properties_2(self, attr_cfg = None):
     """get_properties_2(self, attr_cfg = None) -> AttributeConfig_2
@@ -208,7 +237,7 @@ def __Attribute__get_properties_3(self, attr_cfg = None):
         attr_cfg = AttributeConfig_3()
     return self._get_properties_3(attr_cfg)
 
-def __Attribute__set_properties(self, attr_cfg, dev):
+def __Attribute__set_properties(self, attr_cfg, dev = None):
     """set_properties(self, attr_cfg, dev) -> None
 
                 Set attribute properties.
@@ -223,10 +252,14 @@ def __Attribute__set_properties(self, attr_cfg, dev):
 
             New in PyTango 7.1.4
     """
-    if isinstance(attr_cfg, AttributeConfig_3):
-        self._set_properties_3(attr_cfg, dev)
+    
+    if isinstance(attr_cfg,MultiAttrProp):
+        return self._set_properties_multi_attr_prop(attr_cfg)
     else:
-        self._set_properties(attr_cfg, dev)
+        if isinstance(attr_cfg, AttributeConfig_3):
+            self._set_properties_3(attr_cfg, dev)
+        else:
+            self._set_properties(attr_cfg, dev)
 
 
 def __DeviceImpl__get_device_class(self):
@@ -261,13 +294,14 @@ def __DeviceImpl__get_device_properties(self, ds_class = None):
         self.device_property_list = copy.deepcopy(ds_class.device_property_list)
         class_prop = ds_class.class_property_list
         pu.get_device_properties(self, class_prop, self.device_property_list)
-        for prop_name in class_prop.keys():
+        for prop_name in class_prop:
             setattr(self, prop_name, pu.get_property_values(prop_name, class_prop))
-        for prop_name in self.device_property_list.keys():
+        for prop_name in self.device_property_list:
             setattr(self, prop_name, self.prop_util.get_property_values(prop_name, self.device_property_list))
-    except _PyTango.DevFailed, e:
-        print "----> ", e
-        raise e
+    except DevFailed as df:
+        print(80*"-")
+        print(df)
+        raise df
 
 def __DeviceImpl__add_attribute(self, attr, r_meth=None, w_meth=None, is_allo_meth=None):
     """add_attribute(self, attr, r_meth=None, w_meth=None, is_allo_meth=None) -> Attr
@@ -392,7 +426,7 @@ def __DeviceImpl__debug_stream(self, *msg):
 
             Since PyTango 7.1.3, the same can be achieved with::
             
-                print >>self.log_debug, msg
+                print(msg, file=self.log_debug)
             
         Parameters :
             - msg : (str) the message to be sent to the debug stream
@@ -408,7 +442,7 @@ def __DeviceImpl__info_stream(self, *msg):
 
             Since PyTango 7.1.3, the same can be achieved with::
             
-                print >>self.log_info, msg
+                print(msg, file=self.log_info)
 
         Parameters :
             - msg : (str) the message to be sent to the info stream
@@ -424,7 +458,7 @@ def __DeviceImpl__warn_stream(self, *msg):
 
             Since PyTango 7.1.3, the same can be achieved with::
             
-                print >>self.log_warn, msg
+                print(msg, file=self.log_warn)
 
         Parameters :
             - msg : (str) the message to be sent to the warn stream
@@ -440,7 +474,7 @@ def __DeviceImpl__error_stream(self, *msg):
 
             Since PyTango 7.1.3, the same can be achieved with::
             
-                print >>self.log_error, msg
+                print(msg, file=self.log_error)
 
         Parameters :
             - msg : (str) the message to be sent to the error stream
@@ -456,7 +490,7 @@ def __DeviceImpl__fatal_stream(self, *msg):
 
             Since PyTango 7.1.3, the same can be achieved with::
             
-                print >>self.log_fatal, msg
+                print(msg, file=self.log_fatal)
 
         Parameters :
             - msg : (str) the message to be sent to the fatal stream
@@ -467,31 +501,31 @@ def __DeviceImpl__fatal_stream(self, *msg):
 @property
 def __DeviceImpl__debug(self):
     if not hasattr(self, "_debug_s"):
-        self._debug_s = log4tango.TangoStream(self.debug_stream)
+        self._debug_s = TangoStream(self.debug_stream)
     return self._debug_s
 
 @property
 def __DeviceImpl__info(self):
     if not hasattr(self, "_info_s"):
-        self._info_s = log4tango.TangoStream(self.info_stream)
+        self._info_s = TangoStream(self.info_stream)
     return self._info_s
 
 @property
 def __DeviceImpl__warn(self):
     if not hasattr(self, "_warn_s"):
-        self._warn_s = log4tango.TangoStream(self.warn_stream)
+        self._warn_s = TangoStream(self.warn_stream)
     return self._warn_s
 
 @property
 def __DeviceImpl__error(self):
     if not hasattr(self, "_error_s"):
-        self._error_s = log4tango.TangoStream(self.error_stream)
+        self._error_s = TangoStream(self.error_stream)
     return self._error_s
 
 @property
 def __DeviceImpl__fatal(self):
     if not hasattr(self, "_fatal_s"):
-        self._fatal_s = log4tango.TangoStream(self.fatal_stream)
+        self._fatal_s = TangoStream(self.fatal_stream)
     return self._fatal_s
 
 def __DeviceImpl__str(self):
@@ -2409,66 +2443,150 @@ def __doc_UserDefaultAttrProp():
     """ )
     
     document_method("set_abs_change", """
-    set_abs_change(self, def_abs_change) -> None
+    set_abs_change(self, def_abs_change) -> None <= DEPRECATED
+
+            Set default change event abs_change property. 
+
+        Parameters :  
+            - def_abs_change : (str) the user default change event abs_change property 
+        Return     : None
+        
+        Deprecated since PyTango 8.0. Please use set_event_abs_change instead.
+    """ )
+
+    document_method("set_event_abs_change", """
+    set_event_abs_change(self, def_abs_change) -> None
 
             Set default change event abs_change property. 
 
         Parameters :  
             - def_abs_change : (str) the user default change event abs_change property 
         Return     : None
+        
+        New in PyTango 8.0
     """ )
     
     document_method("set_rel_change", """
-    set_rel_change(self, def_rel_change) -> None
+    set_rel_change(self, def_rel_change) -> None <= DEPRECATED
 
             Set default change event rel_change property. 
 
         Parameters :  
             - def_rel_change : (str) the user default change event rel_change property 
         Return     : None
+        
+        Deprecated since PyTango 8.0. Please use set_event_rel_change instead.
+    """ )
+
+    document_method("set_event_rel_change", """
+    set_event_rel_change(self, def_rel_change) -> None
+
+            Set default change event rel_change property. 
+
+        Parameters :  
+            - def_rel_change : (str) the user default change event rel_change property 
+        Return     : None
+        
+        New in PyTango 8.0
     """ )
     
     document_method("set_period", """ 
-    set_period(self, def_period) -> None
+    set_period(self, def_period) -> None <= DEPRECATED
 
             Set default periodic event period property. 
 
         Parameters :  
             - def_period : (str) the user default periodic event period property 
         Return     : None
+        
+        Deprecated since PyTango 8.0. Please use set_event_period instead.
     """ )
 
+    document_method("set_event_period", """ 
+    set_event_period(self, def_period) -> None
+
+            Set default periodic event period property. 
+
+        Parameters :  
+            - def_period : (str) the user default periodic event period property 
+        Return     : None
+        
+        New in PyTango 8.0
+    """ )
+    
     document_method("set_archive_abs_change", """
-    set_archive_abs_change(self, def_archive_abs_change) -> None
+    set_archive_abs_change(self, def_archive_abs_change) -> None <= DEPRECATED
 
             Set default archive event abs_change property. 
 
         Parameters :  
             - def_archive_abs_change : (str) the user default archive event abs_change property 
         Return     : None
+        
+        Deprecated since PyTango 8.0. Please use set_archive_event_abs_change instead.
     """ )
 
+    document_method("set_archive_event_abs_change", """
+    set_archive_event_abs_change(self, def_archive_abs_change) -> None
+
+            Set default archive event abs_change property. 
+
+        Parameters :  
+            - def_archive_abs_change : (str) the user default archive event abs_change property 
+        Return     : None
+        
+        New in PyTango 8.0
+    """ )
+    
     document_method("set_archive_rel_change", """
-    set_archive_rel_change(self, def_archive_rel_change) -> None
+    set_archive_rel_change(self, def_archive_rel_change) -> None <= DEPRECATED
+
+            Set default archive event rel_change property. 
+
+        Parameters :  
+            - def_archive_rel_change : (str) the user default archive event rel_change property 
+        Return     : None
+        
+        Deprecated since PyTango 8.0. Please use set_archive_event_rel_change instead.
+    """ )
+
+    document_method("set_archive_event_rel_change", """
+    set_archive_event_rel_change(self, def_archive_rel_change) -> None
 
             Set default archive event rel_change property. 
 
         Parameters :  
             - def_archive_rel_change : (str) the user default archive event rel_change property 
         Return     : None
+        
+        New in PyTango 8.0
     """ )
     
     document_method("set_archive_period", """
-    set_archive_period(self, def_archive_period) -> None
+    set_archive_period(self, def_archive_period) -> None <= DEPRECATED
 
             Set default archive event period property. 
 
         Parameters :  
             - def_archive_period : (str) t
         Return     : None
+        
+        Deprecated since PyTango 8.0. Please use set_archive_event_period instead.
+    """ )
+
+    document_method("set_archive_event_period", """
+    set_archive_event_period(self, def_archive_period) -> None
+
+            Set default archive event period property. 
+
+        Parameters :  
+            - def_archive_period : (str) t
+        Return     : None
+        
+        New in PyTango 8.0
     """ )
     
-def init(doc=True):
+def device_server_init(doc=True):
     __init_DeviceImpl()
     __init_Attribute()
     __init_Attr()
diff --git a/PyTango/encoded_attribute.py b/PyTango/encoded_attribute.py
index afaefd5..d23d784 100644
--- a/PyTango/encoded_attribute.py
+++ b/PyTango/encoded_attribute.py
@@ -25,19 +25,18 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["encoded_attribute_init"]
 
 __docformat__ = "restructuredtext"
 
-import types
-import operator
+import collections
 
-import _PyTango
-from _PyTango import EncodedAttribute
-from _PyTango import ExtractAs
-from _PyTango import _ImageFormat
+from ._PyTango import EncodedAttribute, ExtractAs, _ImageFormat
+from ._PyTango import constants
 
-if _PyTango.constants.NUMPY_SUPPORT:
+from .utils import is_pure_str, is_seq
+
+if constants.NUMPY_SUPPORT:
     try:
         import numpy
         np = numpy
@@ -47,7 +46,7 @@ else:
     np = None
     
 _allowed_extract = ExtractAs.Numpy, ExtractAs.String, ExtractAs.Tuple, \
-                   ExtractAs.List, ExtractAs.PyTango3
+                   ExtractAs.List
 
 def __EncodedAttribute_encode_jpeg_gray8(self, gray8, width=0, height=0, quality=100.0):
     """Encode a 8 bit grayscale image as JPEG format
@@ -123,11 +122,11 @@ def __EncodedAttribute_encode_gray8(self, gray8, width=0, height=0):
 
 def __EncodedAttribute_generic_encode_gray8(self, gray8, width=0, height=0, quality=0, format=_ImageFormat.RawImage):
     """Internal usage only"""
-    if not operator.isSequenceType(gray8):
+    if not is_seq(gray8):
         raise TypeError("Expected sequence (str, numpy.ndarray, list, tuple "
                         "or bytearray) as first argument")
     
-    is_str = type(gray8) in types.StringTypes
+    is_str = is_pure_str(gray8)
     if is_str:
         if not width or not height:
             raise ValueError("When giving a string as data, you must also "
@@ -156,7 +155,7 @@ def __EncodedAttribute_generic_encode_gray8(self, gray8, width=0, height=0, qual
             raise IndexError("Expected sequence with at least one row")
         
         row0 = gray8[0]
-        if not operator.isSequenceType(row0):
+        if not is_seq(row0):
             raise IndexError("Expected sequence (str, numpy.ndarray, list, tuple or "
                              "bytearray) inside a sequence")
         width = len(row0)
@@ -199,11 +198,11 @@ def __EncodedAttribute_encode_gray16(self, gray16, width=0, height=0):
                enc.encode_gray16(data)
                attr.set_value(data)
     """
-    if not operator.isSequenceType(gray16):
+    if not is_seq(gray16):
         raise TypeError("Expected sequence (str, numpy.ndarray, list, tuple "
                         "or bytearray) as first argument")
     
-    is_str = type(gray16) in types.StringTypes
+    is_str = is_pure_str(gray16)
     if is_str:
         if not width or not height:
             raise ValueError("When giving a string as data, you must also "
@@ -233,11 +232,11 @@ def __EncodedAttribute_encode_gray16(self, gray16, width=0, height=0):
             raise IndexError("Expected sequence with at least one row")
         
         row0 = gray16[0]
-        if not operator.isSequenceType(row0):
+        if not is_seq(row0):
             raise IndexError("Expected sequence (str, numpy.ndarray, list, tuple or "
                              "bytearray) inside a sequence")
         width = len(row0)
-        if type(row0) in types.StringTypes or type(row0) == bytearray:
+        if is_pure_str(row0) or type(row0) == bytearray:
             width /= 2
     
     self._encode_gray16(gray16, width, height)
@@ -318,11 +317,11 @@ def __EncodedAttribute_encode_rgb24(self, rgb24, width=0, height=0):
     
 def __EncodedAttribute_generic_encode_rgb24(self, rgb24, width=0, height=0, quality=0, format=_ImageFormat.RawImage):
     """Internal usage only"""
-    if not operator.isSequenceType(rgb24):
+    if not is_seq(rgb24):
         raise TypeError("Expected sequence (str, numpy.ndarray, list, tuple "
                         "or bytearray) as first argument")
     
-    is_str = type(rgb24) in types.StringTypes
+    is_str = is_pure_str(rgb24)
     if is_str:
         if not width or not height:
             raise ValueError("When giving a string as data, you must also "
@@ -351,11 +350,11 @@ def __EncodedAttribute_generic_encode_rgb24(self, rgb24, width=0, height=0, qual
             raise IndexError("Expected sequence with at least one row")
         
         row0 = rgb24[0]
-        if not operator.isSequenceType(row0):
+        if not is_seq(row0):
             raise IndexError("Expected sequence (str, numpy.ndarray, list, tuple or "
                              "bytearray) inside a sequence")
         width = len(row0)
-        if type(row0) in types.StringTypes or type(row0) == bytearray:
+        if is_pure_str(row0) or type(row0) == bytearray:
             width /= 3
     if format == _ImageFormat.RawImage:
         self._encode_rgb24(rgb24, width, height)
@@ -394,11 +393,11 @@ def __EncodedAttribute_encode_jpeg_rgb32(self, rgb32, width=0, height=0, quality
                enc.encode_jpeg_rgb32(data)
                attr.set_value(data)
     """
-    if not operator.isSequenceType(rgb32):
+    if not is_seq(rgb32):
         raise TypeError("Expected sequence (str, numpy.ndarray, list, tuple "
                         "or bytearray) as first argument")
     
-    is_str = type(rgb32) in types.StringTypes
+    is_str = is_pure_str(rgb32)
     if is_str:
         if not width or not height:
             raise ValueError("When giving a string as data, you must also "
@@ -427,11 +426,11 @@ def __EncodedAttribute_encode_jpeg_rgb32(self, rgb32, width=0, height=0, quality
             raise IndexError("Expected sequence with at least one row")
         
         row0 = rgb32[0]
-        if not operator.isSequenceType(row0):
+        if not is_seq(row0):
             raise IndexError("Expected sequence (str, numpy.ndarray, list, tuple or "
                              "bytearray) inside a sequence")
         width = len(row0)
-        if type(row0) in types.StringTypes or type(row0) == bytearray:
+        if is_pure_str(row0) or type(row0) == bytearray:
             width /= 4
 
     self._encode_jpeg_rgb32(rgb32, width, height, quality)
@@ -469,7 +468,7 @@ def __EncodedAttribute_decode_gray8(self, da, extract_as=ExtractAs.Numpy):
         raise TypeError("DeviceAttribute argument must have been obtained from "
                         "a call which doesn't extract the contents")
     if extract_as not in _allowed_extract:
-        raise TypeError("extract_as must be one of Numpy, String, Tuple, List, PyTango3")
+        raise TypeError("extract_as must be one of Numpy, String, Tuple, List")
     return self._decode_gray8(da, extract_as)
 
 def __EncodedAttribute_decode_gray16(self, da, extract_as=ExtractAs.Numpy):
@@ -504,7 +503,7 @@ def __EncodedAttribute_decode_gray16(self, da, extract_as=ExtractAs.Numpy):
         raise TypeError("DeviceAttribute argument must have been obtained from "
                         "a call which doesn't extract the contents")
     if extract_as not in _allowed_extract:
-        raise TypeError("extract_as must be one of Numpy, String, Tuple, List, PyTango3")
+        raise TypeError("extract_as must be one of Numpy, String, Tuple, List")
     return self._decode_gray16(da, extract_as)
 
 def __EncodedAttribute_decode_rgb32(self, da, extract_as=ExtractAs.Numpy):
@@ -539,7 +538,7 @@ def __EncodedAttribute_decode_rgb32(self, da, extract_as=ExtractAs.Numpy):
         raise TypeError("DeviceAttribute argument must have been obtained from "
                         "a call which doesn't extract the contents")
     if extract_as not in _allowed_extract:
-        raise TypeError("extract_as must be one of Numpy, String, Tuple, List, PyTango3")
+        raise TypeError("extract_as must be one of Numpy, String, Tuple, List")
     return self._decode_rgb32(da, extract_as)
 
 def __init_EncodedAttribute():
@@ -558,7 +557,7 @@ def __init_EncodedAttribute():
 def __doc_EncodedAttribute():
     pass
 
-def init(doc=True):
+def encoded_attribute_init(doc=True):
     __init_EncodedAttribute()
     if doc:
         __doc_EncodedAttribute()
diff --git a/PyTango/exception.py b/PyTango/exception.py
index 5aaacf9..b172e04 100644
--- a/PyTango/exception.py
+++ b/PyTango/exception.py
@@ -25,12 +25,12 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["exception_init"]
 
 __docformat__ = "restructuredtext"
 
-from utils import document_static_method as __document_static_method
-from _PyTango import Except, DevError
+from .utils import document_static_method as __document_static_method
+from ._PyTango import Except, DevError
 
 def __to_dev_failed(exc_type=None, exc_value=None, traceback=None):
     """to_dev_failed(exc_type, exc_value, traceback) -> PyTango.DevFailed
@@ -55,7 +55,7 @@ def __to_dev_failed(exc_type=None, exc_value=None, traceback=None):
         New in PyTango 7.2.1"""
     try:
         Except.throw_python_exception(exc_type, exc_value, traceback)
-    except Exception, e:
+    except Exception as e:
         return e
 
 def __init_Except():
@@ -160,7 +160,7 @@ def __doc_DevError():
         - origin : (str) Tango server method in which the error happened"""
 
   
-def init(doc=True):
+def exception_init(doc=True):
     __init_Except()
     if doc:
         __doc_Except()
diff --git a/PyTango/globals.py b/PyTango/globals.py
index 409da54..e288607 100644
--- a/PyTango/globals.py
+++ b/PyTango/globals.py
@@ -101,8 +101,8 @@ def class_factory():
     local_cpp_class_list = get_cpp_classes()
 
     if ((len(local_class_list) + len(local_cpp_class_list)) == 0):
-        print 'Oups, no Tango class defined within this device server !!!'
-        print 'Sorry, but I exit'
+        print('Oups, no Tango class defined within this device server !!!')
+        print('Sorry, but I exit')
         import sys
         sys.exit()
 
diff --git a/PyTango/group.py b/PyTango/group.py
index fd46e6e..c121e9b 100644
--- a/PyTango/group.py
+++ b/PyTango/group.py
@@ -25,14 +25,31 @@
 This is an internal PyTango module.
 """
 
-__all__ = [ "Group" ]
+__all__ = [ "Group", "group_init" ]
 
 __docformat__ = "restructuredtext"
 
-from _PyTango import __Group as _RealGroup, GroupElement
-from utils import document_method as __document_method
+import operator
 
-import group_element
+from ._PyTango import __Group as _RealGroup, StdStringVector
+from .utils import seq_2_StdStringVector
+from .utils import document_method as __document_method
+import collections
+
+def _apply_to(fn, key):
+    if isinstance(key, slice):
+        if key.step:
+            return [ fn(x) for x in range(key.start, key.stop, key.step) ]
+        else:
+            return [ fn(x) for x in range(key.start, key.stop) ]
+    else:
+        return fn(key)
+
+def _get_one_item(group, key):
+    x = group.get_group(key)
+    if x is not None:
+        return x
+    return group.get_device(key)
 
 # I define Group as a proxy to __Group, where group is the actual
 # C++ Tango::Group object. Most functions just call the __group object
@@ -44,31 +61,89 @@ import group_element
 # The other function that needs to be adapted to this is get_group because
 # we want to return a Group, not a __Group!
 class Group:
+    """A Tango Group represents a hierarchy of tango devices. The hierarchy
+    may have more than one level. The main goal is to group devices with
+    same attribute(s)/command(s) to be able to do parallel requests."""
+    
     def __init__(self, name):
         if isinstance(name, str):
             name = _RealGroup(name)
         if not isinstance(name, _RealGroup):
             raise TypeError("Constructor expected receives a str")
         self.__group = name
-
+    
     def add(self, pattern_subgroup, timeout_ms=-1):
         if isinstance(pattern_subgroup, Group):
             name = pattern_subgroup.__group.get_name()
-            self.__group.add(pattern_subgroup.__group, timeout_ms)
+            self._add(pattern_subgroup.__group, timeout_ms)
             pattern_subgroup.__group = self.get_group(name)
         else:
-            self.__group.add(pattern_subgroup, timeout_ms)
+            self._add(pattern_subgroup, timeout_ms)
+
+    def _add(self, patterns_or_group, timeout_ms=-1):
+        if isinstance(patterns_or_group, _RealGroup):
+            return self.__group._add(patterns_or_group, timeout_ms)
+        elif isinstance(patterns_or_group, StdStringVector):
+            return self.__group._add(patterns_or_group, timeout_ms)
+        elif isinstance(patterns_or_group, str):
+            return self.__group._add(patterns_or_group, timeout_ms)
+        elif isinstance(patterns_or_group, collections.Sequence):
+            patterns = seq_2_StdStringVector(patterns_or_group)
+            return self.__group._add(patterns, timeout_ms)
+        else:
+            raise TypeError('Parameter patterns_or_group: Should be Group, str or a sequence of strings.')
+
+    def remove(self, patterns, forward=True):
+        if isinstance(patterns, str):
+            return self.__group._remove(patterns, forward)
+        elif isinstance(patterns, collections.Sequence):
+            std_patterns = seq_2_StdStringVector(patterns)
+            return self.__group._remove(std_patterns, forward)
+        else:
+            raise TypeError('Parameter patterns: Should be a str or a sequence of str.')
 
     def get_group(self, group_name):
         internal = self.__group.get_group(group_name)
         if internal is None:
             return None
         return Group(internal)
+    
+    def __contains__(self, pattern):
+        return self.contains(pattern)
+        
+    def __getitem__(self, key):
+        fn = lambda x: _get_one_item(self, x)
+        return _apply_to(fn, key)
+
+    def __delitem__(self, key):
+        fn = lambda x: self.remove(x)
+        return _apply_to(fn, key)
+
+    def __len__(self):
+        return self.get_size()
+
+    def command_inout(self, cmd_name, param=None, forward=True):
+        if param is None:
+            idx = self.command_inout_asynch(cmd_name, forget=False, forward=forward)
+        else:
+            idx = self.command_inout_asynch(cmd_name, param, forget=False, forward=forward)
+        return self.command_inout_reply(idx)
+
+    def read_attribute(self, attr_name, forward=True):
+        idx = self.__group.read_attribute_asynch(attr_name, forward)
+        return self.__group.read_attribute_reply(idx)
+
+    def read_attributes(self, attr_names, forward=True):
+        idx = self.__group.read_attributes_asynch(attr_names, forward)
+        return self.__group.read_attributes_reply(idx)
+
+    def write_attribute(self, attr_name, value, forward=True, multi=False):
+        idx = self.__group.write_attribute_asynch(attr_name, value, forward=forward, multi=multi)
+        return self.__group.write_attribute_reply(idx)
 
 def __init_proxy_Group():
     proxy_methods = [
         #'add',
-        'command_inout',
         'command_inout_asynch',
         'command_inout_reply',
         'contains',
@@ -84,22 +159,14 @@ def __init_proxy_Group():
         'name_equals',
         'name_matches',
         'ping',
-        'read_attribute',
         'read_attribute_asynch',
         'read_attribute_reply',
-        'read_attributes',
         'read_attributes_asynch',
         'read_attributes_reply',
-        'remove',
         'remove_all',
         'set_timeout_millis',
-        'write_attribute',
         'write_attribute_asynch',
-        'write_attribute_reply',
-        '__contains__',
-        '__delitem__',
-        '__getitem__',
-        '__len__']
+        'write_attribute_reply',]
         
     def proxy_call_define(fname):
         def fn(self, *args, **kwds):
@@ -110,44 +177,164 @@ def __init_proxy_Group():
     for fname in proxy_methods:
         proxy_call_define(fname)
     
-    Group.add.im_func.__doc__ = _RealGroup.add.__doc__
-    Group.get_group.im_func.__doc__ = _RealGroup.get_group.__doc__
-    Group.__doc__ = _RealGroup.__doc__
+    #Group.add.im_func.__doc__ = _RealGroup.add.__doc__
+    #Group.get_group.im_func.__doc__ = _RealGroup.get_group.__doc__
+    #Group.__doc__ = _RealGroup.__doc__
 
 
 def __doc_Group():
     def document_method(method_name, desc, append=True):
         return __document_method(_RealGroup, method_name, desc, append)
 
-    document_method("add", GroupElement.add.__doc__, False)
-    document_method("add", """
-    add(self, subgroup, timeout_ms=-1) -> None
+    document_method("_add", """
+    add(self, patterns, timeout_ms=-1) -> None
         
-            Attaches a (sub)_RealGroup.
-            
-            To remove the subgroup use the remove() method.
+            Attaches any device which name matches one of the specified patterns.
+
+            This method first asks to the Tango database the list of device names
+            matching one the patterns. Devices are then attached to the group in
+            the order in which they are returned by the database.
+
+            Any device already present in the hierarchy (i.e. a device belonging to
+            the group or to one of its subgroups), is silently ignored but its
+            client side timeout is set to timeout_ms milliseconds if timeout_ms
+            is different from -1.
 
         Parameters :
-            - subgroup   : (str)
-            - timeout_ms : (int) If timeout_ms parameter is different from -1,
-                            the client side timeout associated to each device
-                            composing the _RealGroup added is set to timeout_ms
-                            milliseconds. If timeout_ms is -1, timeouts are
-                            not changed.
+            - patterns   : (str | sequence<str>) can be a simple device name or
+                            a device name pattern (e.g. domain_*/ family/member_*),
+                            or a sequence of these.
+            - timeout_ms : (int) If timeout_ms is different from -1, the client
+                            side timeouts of all devices matching the
+                            specified patterns are set to timeout_ms
+                            milliseconds.
         Return     : None
 
         Throws     : TypeError, ArgumentError
     """ )
 
+    document_method("_remove", """
+    remove(self, patterns, forward=True) -> None
+        
+            Removes any group or device which name matches the specified pattern. 
+            
+            The pattern parameter can be a group name, a device name or a device
+            name pattern (e.g domain_*/family/member_*).
+            
+            Since we can have groups with the same name in the hierarchy, a group
+            name can be fully qualified to specify which group should be removed.
+            Considering the following group:
+
+                ::
+
+                    -> gauges 
+                    | -> cell-01 
+                    |     |-> penning 
+                    |     |    |-> ...
+                    |     |-> pirani
+                    |          |-> ...
+                    | -> cell-02
+                    |     |-> penning
+                    |     |    |-> ...
+                    |     |-> pirani
+                    |          |-> ...
+                    | -> cell-03
+                    |     |-> ... 
+                    |     
+                    | -> ...  
+            
+            A call to gauges->remove("penning") will remove any group named
+            "penning" in the hierarchy while gauges->remove("gauges.cell-02.penning")
+            will only remove the specified group.
+        
+        Parameters :
+            - patterns   : (str | sequence<str>) A string with the pattern or a
+                           list of patterns.
+            - forward    : (bool) If fwd is set to true (the default), the remove
+                           request is also forwarded to subgroups. Otherwise,
+                           it is only applied to the local set of elements.
+                           For instance, the following code remove any
+                           stepper motor in the hierarchy:
+                           
+                               root_group->remove("*/stepper_motor/*");
+                
+        Return     : None
+        
+        Throws     : 
+    """ )
+
     document_method("remove_all", """
     remove_all(self) -> None
     
         Removes all elements in the _RealGroup. After such a call, the _RealGroup is empty.
     """ )
 
-    # I just documented them in group_element.py ...
-    #document_method("enable", """""" )
-    #document_method("disable", """""" )
+    document_method("contains", """
+    contains(self, pattern, forward=True) -> bool
+        
+        Parameters :
+            - pattern    : (str) The pattern can be a fully qualified or simple
+                            group name, a device name or a device name pattern.
+            - forward    : (bool) If fwd is set to true (the default), the remove
+                            request is also forwarded to subgroups. Otherwise,
+                            it is only applied to the local set of elements.
+                
+        Return     : (bool) Returns true if the hierarchy contains groups and/or
+                     devices which name matches the specified pattern. Returns
+                     false otherwise.
+        
+        Throws     : 
+    """ )
+
+
+    document_method("get_device", """
+    get_device(self, dev_name) -> DeviceProxy
+    get_device(self, idx) -> DeviceProxy
+
+            Returns a reference to the specified device or None if there is no
+            device by that name in the group. Or, returns a reference to the
+            "idx-th" device in the hierarchy or NULL if the hierarchy contains
+            less than "idx" devices.
+
+            This method may throw an exception in case the specified device belongs
+            to the group but can't be reached (not registered, down...). See example
+            below:
+
+            ::
+
+                try:
+                    dp = g.get_device("my/device/01")
+                    if dp is None:
+                        # my/device/01 does not belong to the group
+                        pass
+                except DevFailed, f:
+                    # my/device/01 belongs to the group but can't be reached
+                    pass
+
+            The request is systematically forwarded to subgroups (i.e. if no device
+            named device_name could be found in the local set of devices, the
+            request is forwarded to subgroups).
+            
+        Parameters :
+            - dev_name    : (str) Device name.
+            - idx         : (int) Device number.
+                
+        Return     : (DeviceProxy) Be aware that this method returns a
+                    different DeviceProxy referring to the same device each time.
+                    So, do not use it directly for permanent things.
+
+        Example:
+                        # WRONG: The DeviceProxy will quickly go out of scope
+                        # and disappear (thus, the event will be automatically
+                        # unsubscribed)
+                        g.get_device("my/device/01").subscribe_events('attr', callback)
+
+                        # GOOD:
+                        dp = g.get_device("my/device/01")
+                        dp.subscribe_events('attr', callback)
+        
+        Throws     : DevFailed
+    """ )
 
     document_method("get_device_list", """
     get_device_list(self, forward=True) -> sequence<str>
@@ -209,9 +396,346 @@ def __doc_Group():
         
         Throws     :
     """ )
+    
+    document_method("get_group", """
+    get_group(self, group_name ) -> Group
+
+            Returns a reference to the specified group or None if there is no group
+            by that name. The group_name can be a fully qualified name.
+
+            Considering the following group:
+
+            ::
+                    
+                -> gauges
+                    |-> cell-01
+                    |    |-> penning
+                    |    |    |-> ... 
+                    |    |-> pirani
+                    |    |-> ... 
+                    |-> cell-02
+                    |    |-> penning
+                    |    |    |-> ...
+                    |    |-> pirani
+                    |    |-> ...
+                    | -> cell-03
+                    |    |-> ...
+                    |
+                    | -> ...  
+
+            A call to gauges.get_group("penning") returns the first group named
+            "penning" in the hierarchy (i.e. gauges.cell-01.penning) while
+            gauges.get_group("gauges.cell-02.penning'') returns the specified group.
+            
+            The request is systematically forwarded to subgroups (i.e. if no group
+            named group_name could be found in the local set of elements, the request
+            is forwarded to subgroups).
+        
+        Parameters :
+            - group_name : (str)
+        
+        Return     : (Group)
+        
+        Throws     :
+        
+        New in PyTango 7.0.0
+    """ )
+
+# Tango methods (~ DeviceProxy interface)
+    document_method("ping", """
+    ping(self, forward=True) -> bool
+
+            Ping all devices in a group.
+        
+        Parameters :
+            - forward    : (bool) If fwd is set to true (the default), the request
+                            is also forwarded to subgroups. Otherwise, it is
+                            only applied to the local set of devices.
+                
+        Return     : (bool) This method returns true if all devices in
+                     the group are alive, false otherwise.
+        
+        Throws     : 
+    """ )
+
+    document_method("set_timeout_millis", """
+    set_timeout_millis(self, timeout_ms) -> bool
+        
+            Set client side timeout for all devices composing the group in
+            milliseconds. Any method which takes longer than this time to execute
+            will throw an exception.
+
+        Parameters :
+            - timeout_ms : (int)
+                
+        Return     : None
+        
+        Throws     : (errors are ignored)
+
+        New in PyTango 7.0.0
+    """ )
+
+    document_method("command_inout_asynch", """
+    command_inout_asynch(self, cmd_name, forget=False, forward=True, reserved=-1 ) -> int
+    command_inout_asynch(self, cmd_name, param, forget=False, forward=True, reserved=-1 ) -> int
+    command_inout_asynch(self, cmd_name, param_list, forget=False, forward=True, reserved=-1 ) -> int
+    
+            Executes a Tango command on each device in the group asynchronously.
+            The method sends the request to all devices and returns immediately.
+            Pass the returned request id to Group.command_inout_reply() to obtain
+            the results.
+
+        Parameters :
+            - cmd_name   : (str) Command name
+            - param      : (any) parameter value
+            - param_list : (PyTango.DeviceDataList) sequence of parameters.
+                           When given, it's length must match the group size.
+            - forget     : (bool) Fire and forget flag. If set to true, it means that
+                           no reply is expected (i.e. the caller does not care
+                           about it and will not even try to get it)
+            - forward    : (bool) If it is set to true (the default) request is
+                            forwarded to subgroups. Otherwise, it is only applied
+                            to the local set of devices.
+            - reserved : (int) is reserved for internal purpose and should not be
+                            used. This parameter may disappear in a near future.
+                
+        Return     : (int) request id. Pass the returned request id to
+                    Group.command_inout_reply() to obtain the results.
+        
+        Throws     :
+    """ )
+
+    document_method("command_inout_reply", """
+    command_inout_reply(self, req_id, timeout_ms=0) -> sequence<GroupCmdReply>
+
+            Returns the results of an asynchronous command.
+
+        Parameters :
+            - req_id     : (int) Is a request identifier previously returned by one
+                            of the command_inout_asynch methods
+            - timeout_ms : (int) For each device in the hierarchy, if the command
+                            result is not yet available, command_inout_reply
+                            wait timeout_ms milliseconds before throwing an
+                            exception. This exception will be part of the
+                            global reply. If timeout_ms is set to 0,
+                            command_inout_reply waits "indefinitely".
+                
+        Return     : (sequence<GroupCmdReply>)
+        
+        Throws     : 
+    """ )
+
+    document_method("read_attribute_asynch", """
+    read_attribute_asynch(self, attr_name, forward=True, reserved=-1 ) -> int
+
+            Reads an attribute on each device in the group asynchronously.
+            The method sends the request to all devices and returns immediately.
+
+        Parameters :
+            - attr_name : (str) Name of the attribute to read.
+            - forward   : (bool) If it is set to true (the default) request is
+                            forwarded to subgroups. Otherwise, it is only applied
+                            to the local set of devices.
+            - reserved  : (int) is reserved for internal purpose and should not be
+                            used. This parameter may disappear in a near future.
+                
+        Return     : (int) request id. Pass the returned request id to
+                    Group.read_attribute_reply() to obtain the results.
+        
+        Throws     :
+    """ )
+
+    document_method("read_attributes_asynch", """
+    read_attributes_asynch(self, attr_names, forward=True, reserved=-1 ) -> int
+
+            Reads the attributes on each device in the group asynchronously.
+            The method sends the request to all devices and returns immediately.
+
+        Parameters :
+            - attr_names : (sequence<str>) Name of the attributes to read.
+            - forward    : (bool) If it is set to true (the default) request is
+                            forwarded to subgroups. Otherwise, it is only applied
+                            to the local set of devices.
+            - reserved   : (int) is reserved for internal purpose and should not be
+                            used. This parameter may disappear in a near future.
+                
+        Return     : (int) request id. Pass the returned request id to
+                    Group.read_attributes_reply() to obtain the results.
+        
+        Throws     :
+    """ )
+
+    document_method("read_attribute_reply", """
+    read_attribute_reply(self, req_id, timeout_ms=0 ) -> sequence<GroupAttrReply>
+
+            Returns the results of an asynchronous attribute reading.
+
+        Parameters :
+            - req_id     : (int) a request identifier previously returned by read_attribute_asynch.
+            - timeout_ms : (int) For each device in the hierarchy, if the attribute
+                            value is not yet available, read_attribute_reply
+                            wait timeout_ms milliseconds before throwing an
+                            exception. This exception will be part of the
+                            global reply. If timeout_ms is set to 0,
+                            read_attribute_reply waits "indefinitely".
+                
+        Return     : (sequence<GroupAttrReply>)
+        
+        Throws     :
+    """ )
+
+    document_method("read_attributes_reply", """
+    read_attributes_reply(self, req_id, timeout_ms=0 ) -> sequence<GroupAttrReply>
+
+            Returns the results of an asynchronous attribute reading.
+
+        Parameters :
+            - req_id     : (int) a request identifier previously returned by read_attribute_asynch.
+            - timeout_ms : (int) For each device in the hierarchy, if the attribute
+                           value is not yet available, read_attribute_reply
+                           ait timeout_ms milliseconds before throwing an
+                           exception. This exception will be part of the
+                           global reply. If timeout_ms is set to 0,
+                           read_attributes_reply waits "indefinitely".
+                
+        Return     : (sequence<GroupAttrReply>)
+        
+        Throws     :
+    """ )
+
+    document_method("write_attribute_asynch", """
+    write_attribute_asynch(self, attr_name, value, forward=True, multi=False ) -> int
+
+            Writes an attribute on each device in the group asynchronously.
+            The method sends the request to all devices and returns immediately.
+
+        Parameters :
+            - attr_name : (str) Name of the attribute to write.
+            - value     : (any) Value to write. See DeviceProxy.write_attribute
+            - forward   : (bool) If it is set to true (the default) request is
+                          forwarded to subgroups. Otherwise, it is only applied
+                          to the local set of devices.
+            - multi     : (bool) If it is set to false (the default), the same
+                          value is applied to all devices in the group.
+                          Otherwise the value is interpreted as a sequence of
+                          values, and each value is applied to the corresponding
+                          device in the group. In this case len(value) must be
+                          equal to group.get_size()!
+                
+        Return     : (int) request id. Pass the returned request id to
+                    Group.write_attribute_reply() to obtain the acknowledgements.
+        
+        Throws     :
+    """ )
+        
+    document_method("write_attribute_reply", """
+    write_attribute_reply(self, req_id, timeout_ms=0 ) -> sequence<GroupReply>
+
+            Returns the acknowledgements of an asynchronous attribute writing.
 
-def init(doc=True):
-    group_element.init(doc=doc)
+        Parameters :
+            - req_id     : (int) a request identifier previously returned by write_attribute_asynch.
+            - timeout_ms : (int) For each device in the hierarchy, if the acknowledgment
+                            is not yet available, write_attribute_reply
+                            wait timeout_ms milliseconds before throwing an
+                            exception. This exception will be part of the
+                            global reply. If timeout_ms is set to 0,
+                            write_attribute_reply waits "indefinitely".
+                
+        Return     : (sequence<GroupReply>)
+        
+        Throws     :
+    """ )
+        
+    document_method("get_name", """
+        Get the name of the group. Eg: Group('name').get_name() == 'name'
+    """ )
+    document_method("get_fully_qualified_name", """
+        Get the complete (dpt-separated) name of the group. This takes into
+        consideration the name of the group and its parents.
+    """ )
+    document_method("enable", "Enables a group or a device element in a group.")
+    document_method("disable", "Disables a group or a device element in a group.")
+    document_method("is_enabled", "Check if a group is enabled.\nNew in PyTango 7.0.0")
+    document_method("name_equals", "New in PyTango 7.0.0")
+    document_method("name_matches", "New in PyTango 7.0.0")
+    document_method("get_size", """
+    get_size(self, forward=True) -> int
+
+        Parameters :
+            - forward : (bool) If it is set to true (the default), the request is
+                        forwarded to sub-groups.
+                
+        Return     : (int) The number of the devices in the hierarchy
+        
+        Throws     :
+    """ )
+    
+    def document_method(method_name, desc, append=True):
+        return __document_method(Group, method_name, desc, append)
+
+    document_method("add", _RealGroup._add.__doc__, False)
+    document_method("add", """
+    add(self, subgroup, timeout_ms=-1) -> None
+        
+            Attaches a (sub)_RealGroup.
+            
+            To remove the subgroup use the remove() method.
+
+        Parameters :
+            - subgroup   : (str)
+            - timeout_ms : (int) If timeout_ms parameter is different from -1,
+                            the client side timeout associated to each device
+                            composing the _RealGroup added is set to timeout_ms
+                            milliseconds. If timeout_ms is -1, timeouts are
+                            not changed.
+        Return     : None
+
+        Throws     : TypeError, ArgumentError
+    """ )
+
+    document_method("command_inout", """
+    command_inout(self, cmd_name, forward=True) -> sequence<GroupCmdReply>
+    command_inout(self, cmd_name, param, forward=True) -> sequence<GroupCmdReply>
+    command_inout(self, cmd_name, param_list, forward=True) -> sequence<GroupCmdReply>
+
+            Just a shortcut to do:
+                self.command_inout_reply(self.command_inout_asynch(...))
+
+        Parameters:
+            - cmd_name   : (str) Command name
+            - param      : (any) parameter value
+            - param_list : (PyTango.DeviceDataList) sequence of parameters.
+                           When given, it's length must match the group size.
+            - forward    : (bool) If it is set to true (the default) request is
+                            forwarded to subgroups. Otherwise, it is only applied
+                            to the local set of devices.
+
+        Return : (sequence<GroupCmdReply>)
+    """ )
+
+    document_method("read_attribute", """
+    read_attribute(self, attr_name, forward=True) -> sequence<GroupAttrReply>
+
+            Just a shortcut to do:
+                self.read_attribute_reply(self.read_attribute_asynch(...))
+    """ )
+
+    document_method("read_attributes", """
+    read_attributes(self, attr_names, forward=True) -> sequence<GroupAttrReply>
+
+            Just a shortcut to do:
+                self.read_attributes_reply(self.read_attributes_asynch(...))
+    """ )
+    
+    document_method("write_attribute", """
+    write_attribute(self, attr_name, value, forward=True, multi=False) -> sequence<GroupReply>
+
+            Just a shortcut to do:
+                self.write_attribute_reply(self.write_attribute_asynch(...))
+    """ )
+    
+def group_init(doc=True):
     if doc:
         __doc_Group()
     __init_proxy_Group()
diff --git a/PyTango/group_element.py b/PyTango/group_element.py
index 29ccc85..16c0a36 100644
--- a/PyTango/group_element.py
+++ b/PyTango/group_element.py
@@ -25,24 +25,24 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["group_element_init"]
 
 __docformat__ = "restructuredtext"
 
 import operator
 
-from _PyTango import StdStringVector
-from _PyTango import GroupElement
+from ._PyTango import StdStringVector, GroupElement
 
-from utils import document_method as __document_method
-from utils import seq_2_StdStringVector
+from .utils import document_method as __document_method
+from .utils import seq_2_StdStringVector
+import collections
 
 def __apply_to(fn, key):
     if isinstance(key, slice):
         if key.step:
-            return [ fn(x) for x in xrange(key.start, key.stop, key.step) ]
+            return [ fn(x) for x in range(key.start, key.stop, key.step) ]
         else:
-            return [ fn(x) for x in xrange(key.start, key.stop) ]
+            return [ fn(x) for x in range(key.start, key.stop) ]
     else:
         return fn(key)
 
@@ -73,7 +73,7 @@ def __GroupElement__add(self, patterns_or_group, timeout_ms=-1):
         return self.__add(patterns_or_group, timeout_ms)
     elif isinstance(patterns_or_group, str):
         return self.__add(patterns_or_group, timeout_ms)
-    elif operator.isSequenceType(patterns_or_group):
+    elif isinstance(patterns_or_group, collections.Sequence):
         patterns = seq_2_StdStringVector(patterns_or_group)
         return self.__add(patterns, timeout_ms)
     else:
@@ -82,7 +82,7 @@ def __GroupElement__add(self, patterns_or_group, timeout_ms=-1):
 def __GroupElement__remove(self, patterns, forward=True):
     if isinstance(patterns, str):
         return self.__remove(patterns, forward)
-    elif operator.isSequenceType(patterns):
+    elif isinstance(patterns, collections.Sequence):
         std_patterns = seq_2_StdStringVector(patterns)
         return self.__remove(std_patterns, forward)
     else:
@@ -579,7 +579,7 @@ def __doc_GroupElement():
     # get_parent(self)
     
 
-def init(doc=True):
+def group_element_init(doc=True):
     __init_GroupElement()
     if doc:
         __doc_GroupElement()
diff --git a/PyTango/group_reply.py b/PyTango/group_reply.py
index 29a75ba..9d045f0 100644
--- a/PyTango/group_reply.py
+++ b/PyTango/group_reply.py
@@ -25,15 +25,12 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["group_reply_init"]
 
 __docformat__ = "restructuredtext"
 
-from utils import document_method as __document_method
-from _PyTango import GroupReply
-from _PyTango import GroupCmdReply
-from _PyTango import GroupAttrReply
-from _PyTango import ExtractAs
+from .utils import document_method as __document_method
+from ._PyTango import GroupReply, GroupCmdReply, GroupAttrReply, ExtractAs
 
 def __GroupCmdReply__get_data(self):
     return self.get_data_raw().extract()
@@ -109,7 +106,7 @@ def __doc_GroupReply():
         Return     : (DeviceAttribute) Whatever is stored there, or None.
     """ )
 
-def init(doc=True):
+def group_reply_init(doc=True):
     __init_GroupReply()
     if doc:
         __doc_GroupReply()
diff --git a/PyTango/group_reply_list.py b/PyTango/group_reply_list.py
index 37fa3c8..272105a 100644
--- a/PyTango/group_reply_list.py
+++ b/PyTango/group_reply_list.py
@@ -25,13 +25,12 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["group_reply_list_init"]
 
 __docformat__ = "restructuredtext"
 
-from _PyTango import GroupReplyList
-from _PyTango import GroupCmdReplyList
-from _PyTango import GroupAttrReplyList
+from ._PyTango import GroupReplyList, GroupCmdReplyList, GroupAttrReplyList
+
 
 def __GroupReplyList__getitem(self, item):
     # Accessing an item in GroupReplyList and friends makes a C++ copy
@@ -47,7 +46,7 @@ def __GroupReplyList__getitem(self, item):
     
     # Slices support
     if isinstance(item, slice):
-        return [self.__getitem__(x) for x in xrange(*item.indices(len(self)))]
+        return [self.__getitem__(x) for x in range(*item.indices(len(self)))]
     
     # We want to get the same cache value for x[-1] as for x[len(x)-1]
     if item < 0:
@@ -72,7 +71,7 @@ def __GroupReplyList__getitem(self, item):
 def __GroupReplyList__iter(self):
     # Same problem as getitem. In this case it is easier for me to just
     # reimplement __iter__ in terms of __getitem__
-    for x in xrange(len(self)):
+    for x in range(len(self)):
         yield self[x]
 
 def __init_GroupReplyList():
@@ -92,7 +91,7 @@ def __init_GroupReplyList():
 def __doc_GroupReplyList():
     pass
 
-def init(doc=True):
+def group_reply_list_init(doc=True):
     __init_GroupReplyList()
     if doc:
         __doc_GroupReplyList()
diff --git a/PyTango/ipython/__init__.py b/PyTango/ipython/__init__.py
index 47c0b1e..6b74895 100644
--- a/PyTango/ipython/__init__.py
+++ b/PyTango/ipython/__init__.py
@@ -30,39 +30,41 @@ from .common import get_python_version, get_python_version_number, \
 
 def default_init_ipython(ip, store=True, pytango=True, colors=True,
                          console=True, magic=True):
-    print "Unsupported IPython version (%s) for tango profile" \
-        % get_ipython_version()
-    print "Supported IPython versions are: >= 0.10"
-    print "Starting normal IPython console..."
+    print("Unsupported IPython version (%s) for tango profile" \
+        % get_ipython_version())
+    print("Supported IPython versions are: >= 0.10")
+    print("Starting normal IPython console...")
 
 def default_install(ipydir=None, verbose=True):
-    print "Unsupported IPython version (%s) for tango profile" \
-        % get_ipython_version()
-    print "Supported IPython versions are: 0.10 to 0.13"
-    print "Tango extension to IPython will NOT be installed."
+    print("Unsupported IPython version (%s) for tango profile" \
+        % get_ipython_version())
+    print("Supported IPython versions are: >= 0.10")
+    print("Tango extension to IPython will NOT be installed.")
 
 init_ipython = default_init_ipython
 install = default_install
 
 ipv = get_ipython_version_list()
 if ipv >= [0, 10] and ipv < [0, 11]:
-    import ipython_00_10
+    from . import ipython_00_10
     init_ipython = ipython_00_10.init_ipython
     install = ipython_00_10.install
+    is_installed = ipython_00_10.is_installed
+    __run = ipython_00_10.run
     load_config = None
     load_ipython_extension = None
     unload_ipython_extension = None
-elif ipv >= [0, 11] and ipv < [0, 12]:
-    import ipython_00_11
+elif ipv >= [0, 11] and ipv < [1, 0]:
+    from . import ipython_00_11
     init_ipython = None
     install = ipython_00_11.install
+    is_installed = ipython_00_11.is_installed
+    __run = ipython_00_11.run
     load_config = ipython_00_11.load_config
     load_ipython_extension = ipython_00_11.load_ipython_extension
     unload_ipython_extension = ipython_00_11.unload_ipython_extension
-elif ipv >= [0, 12] and ipv < [1, 0]:
-    import ipython_00_12
-    init_ipython = None
-    install = ipython_00_12.install
-    load_config = ipython_00_12.load_config
-    load_ipython_extension = ipython_00_12.load_ipython_extension
-    unload_ipython_extension = ipython_00_12.unload_ipython_extension
+
+def run():
+    if not is_installed():
+        install(verbose=False)
+    __run()
diff --git a/PyTango/ipython/common.py b/PyTango/ipython/common.py
index 4f89348..8876a09 100644
--- a/PyTango/ipython/common.py
+++ b/PyTango/ipython/common.py
@@ -46,7 +46,7 @@ def translate_version_str2int(version_str):
             v += int(parts[i])*int(math.pow(10,(2-i)*2))
             l -= 1
             i += 1
-        except ValueError,ve:
+        except ValueError:
             return v
         if not l: return v
     return v
@@ -54,21 +54,21 @@ def translate_version_str2int(version_str):
     try:
         v += 10000*int(parts[0])
         l -= 1
-    except ValueError,ve:
+    except ValueError:
         return v
     if not l: return v
     
     try:
         v += 100*int(parts[1])
         l -= 1
-    except ValueError,ve:
+    except ValueError:
         return v
     if not l: return v
 
     try:
         v += int(parts[0])
         l -= 1
-    except ValueError,ve:
+    except ValueError:
         return v
     if not l: return v
 
@@ -109,12 +109,12 @@ def get_ipython_version():
     try:
         try:
             v = IPython.Release.version
-        except Exception, e1:
+        except:
             try:
                 v = IPython.release.version
-            except Exception, e2:
+            except:
                 pass
-    except Exception, e3:
+    except:
         pass
     return v
 
diff --git a/PyTango/ipython/ipython_00_10/ipy_cli.py b/PyTango/ipython/eventlogger.py
similarity index 78%
rename from PyTango/ipython/ipython_00_10/ipy_cli.py
rename to PyTango/ipython/eventlogger.py
index 53931b1..a05b445 100644
--- a/PyTango/ipython/ipython_00_10/ipy_cli.py
+++ b/PyTango/ipython/eventlogger.py
@@ -21,15 +21,17 @@
 ##
 ################################################################################
 
-import re
-import StringIO
+from __future__ import print_function
 
-import IPython.genutils
+import re
+import io
+import operator
 
 class EventLogger(object):
     
-    def __init__(self, capacity=100000):
+    def __init__(self, capacity=100000, pager=None):
         self._capacity = capacity
+        self._pager = pager
         self._records = []
         
     def push_event(self, evt):
@@ -62,11 +64,13 @@ class EventLogger(object):
         if aexpr is not None:
             aexpr = re.compile(aexpr, re.IGNORECASE)
             
-        s = StringIO.StringIO()
-        cols = 4, 30, 18, 20, 12, 16
-        l = "%{0}s %{1}s %{2}s %{3}s %{4}s %{5}s".format(*cols)
-        print >>s, l % ('ID', 'Device', 'Attribute', 'Value', 'Quality', 'Time')
-        print >>s, l % (cols[0]*"-", cols[1]*"-", cols[2]*"-", cols[3]*"-", cols[4]*"-", cols[5]*"-")
+        s = io.BytesIO()
+        lengths = 4, 30, 18, 20, 12, 16
+        title = 'ID', 'Device', 'Attribute', 'Value', 'Quality', 'Time'
+        templ = "{0:{l[0]}} {1:{l[1]}} {2:{l[2]}} {3:{l[3]}} {4:{l[4]}} {5:{l[5]}}"
+        print(templ.format(*title, l=lengths), file=s)
+        print(*map(operator.mul, lengths, len(lengths)*"-"), file=s)
+        
         for i,r in enumerate(self._records):
             if dexpr is not None and not dexpr.match(r.dev_name): continue
             if aexpr is not None and not aexpr.match(r.s_attr_name): continue
@@ -78,6 +82,10 @@ class EventLogger(object):
                 v = str(r.attr_value.value)
                 q = str(r.attr_value.quality)
                 ts = r.attr_value.time.strftime("%H:%M:%S.%f")
-            print >>s, l % (i, r.dev_name, r.s_attr_name, v, q, ts)
+            msg = templ.format(i, r.dev_name, r.s_attr_name, v, q, ts, l=lengths)
+            print(msg, file=s)
         s.seek(0)
-        IPython.genutils.page(s.read())
\ No newline at end of file
+        if self._pager is None:
+            print(s.read())
+        else:
+            self._pager(s.read())
diff --git a/PyTango/ipython/ipython_00_10/__init__.py b/PyTango/ipython/ipython_00_10/__init__.py
index 5e94cb6..06b5776 100644
--- a/PyTango/ipython/ipython_00_10/__init__.py
+++ b/PyTango/ipython/ipython_00_10/__init__.py
@@ -23,5 +23,5 @@
 
 __all__ = ['init_ipython', 'install']
 
-from ipython_00_10 import init_ipython
-from ipy_install import install
\ No newline at end of file
+from .ipython_00_10 import init_ipython, run
+from .ipy_install import install, is_installed
diff --git a/PyTango/ipython/ipython_00_10/ipy_install.py b/PyTango/ipython/ipython_00_10/ipy_install.py
index aa7e058..6e27c74 100644
--- a/PyTango/ipython/ipython_00_10/ipy_install.py
+++ b/PyTango/ipython/ipython_00_10/ipy_install.py
@@ -25,7 +25,7 @@
 
 import sys
 import os
-import StringIO
+import io
 
 import IPython.genutils
 import PyTango
@@ -44,33 +44,39 @@ PyTango.ipython.init_ipython(ip)
 
 """
 
+def is_installed(ipydir=None):
+    install_dir = ipydir or IPython.genutils.get_ipython_dir()
+    f_name = os.path.join(install_dir, 'ipy_profile_tango.py')
+    return os.path.isfile(f_name)
+    
+
 def install(ipydir=None,verbose=True):
     install_dir = ipydir or IPython.genutils.get_ipython_dir()
     f_name = os.path.join(install_dir, 'ipy_profile_tango.py')
     if verbose:
         out = sys.stdout
     else:
-        out = StringIO.StringIO()
+        out = io.StringIO()
     if ipydir is None and os.path.isfile(f_name):
-        print "Warning: The file '%s' already exists." % f_name
+        print("Warning: The file '%s' already exists." % f_name)
         r = ''
         while r.lower() not in ('y', 'n'):
-            r = raw_input("Do you wish to override it [Y/n]?")
+            r = input("Do you wish to override it [Y/n]?")
             r = r or 'y'
         if r.lower() == 'n':
             return
     profile = __PROFILE.format(pytangover=PyTango.Release.version, ipyver=IPython.Release.version)
     
-    out.write("Installing tango extension to ipython... ")
+    out.write(u"Installing tango extension to ipython... ")
     out.flush()
     try:
-        f = file(f_name, "w")
+        f = open(f_name, "w")
         f.write(profile)
         f.close()
-        out.write("[DONE]\n\n")
-    except Exception, e:
-        out.write("[FAILED]\n\n")
-        raise e
+        out.write(u"[DONE]\n\n")
+    except:
+        out.write(u"[FAILED]\n\n")
+        raise
     
     ipy_user_config = os.path.join(IPython.genutils.get_ipython_dir(), 'ipy_user_conf.py')
     out.write("""\
diff --git a/PyTango/ipython/ipython_00_10/ipy_qt.py b/PyTango/ipython/ipython_00_10/ipy_qt.py
index 5485fcf..38bd4c6 100644
--- a/PyTango/ipython/ipython_00_10/ipy_qt.py
+++ b/PyTango/ipython/ipython_00_10/ipy_qt.py
@@ -319,7 +319,7 @@ class EventLoggerTable(Qt.QTableView):
         """Overwrite of slot rows inserted to do proper resize and scroll to 
         bottom if desired
         """
-        for i in xrange(start,end+1):
+        for i in range(start,end+1):
             self.resizeRowToContents(i)
         if start == 0:
             self.resizeColumnsToContents()
diff --git a/PyTango/ipython/ipython_00_10/ipython_00_10.py b/PyTango/ipython/ipython_00_10/ipython_00_10.py
index e486bf4..f6b3933 100644
--- a/PyTango/ipython/ipython_00_10/ipython_00_10.py
+++ b/PyTango/ipython/ipython_00_10/ipython_00_10.py
@@ -25,10 +25,12 @@
 
 """An IPython profile designed to provide a user friendly interface to Tango"""
 
+from __future__ import print_function
+
 import sys
 import os
 import re
-import StringIO
+import io
 import textwrap
 import IPython.ipapi
 import IPython.ColorANSI
@@ -244,18 +246,18 @@ def magic_lsdev(self, parameter_s=''):
     
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database. Device list is empty"
+        print("You are not connected to any Tango Database. Device list is empty")
         return
     data = db._db_cache.devices
 
-    s = StringIO.StringIO()
+    s = io.BytesIO()
     cols = 40, 25, 25, 20
     l = "%{0}s %{1}s %{2}s %{3}s".format(*cols)
-    print >>s, l % ("Device", "Alias", "Server", "Class")
-    print >>s, l % (cols[0]*"-", cols[1]*"-", cols[2]*"-", cols[3]*"-")
+    print(l % ("Device", "Alias", "Server", "Class"), file=s)
+    print(l % (cols[0]*"-", cols[1]*"-", cols[2]*"-", cols[3]*"-"), file=s)
     for d, v in data.items():
         if reg_exp and not reg_exp.match(d): continue
-        print >>s, l % (d, v[0], v[1], v[2])
+        print(l % (d, v[0], v[1], v[2]), file=s)
     s.seek(0)
     IPython.genutils.page(s.read())
 
@@ -275,11 +277,11 @@ def magic_lsdevclass(self, parameter_s=''):
     
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database. Device class list is empty"
+        print("You are not connected to any Tango Database. Device class list is empty")
         return
     data = db._db_cache.klasses
 
-    s = StringIO.StringIO()
+    s = io.BytesIO()
     data = [ "%-030s" % klass for klass in data.keys() if not reg_exp or reg_exp.match(klass) ]
     s = textwrap.fill(" ".join(data), 80)
     IPython.genutils.page(s)
@@ -300,11 +302,11 @@ def magic_lsserv(self, parameter_s=''):
     
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database. Device class list is empty"
+        print("You are not connected to any Tango Database. Device class list is empty")
         return
     data = db._db_cache.servers
 
-    s = StringIO.StringIO()
+    s = io.BytesIO()
     data = [ "%-030s" % server for server in data.keys() if not reg_exp or reg_exp.match(server) ]
     s = textwrap.fill(" ".join(data), 80)
     IPython.genutils.page(s)
@@ -315,10 +317,10 @@ def magic_tango_error(self, parameter_s=''):
     global _TANGO_ERR
     err_info = self.user_ns.get(_TANGO_ERR)
     if err_info is None:
-        print "No tango error reported so far."
+        print("No tango error reported so far.")
         return
-    print "Last tango error:"
-    print err_info[1]
+    print("Last tango error:")
+    print(err_info[1])
 
 def magic_python_error(self, parameter_s=''):
     """Displays detailed information about the last python error"""
@@ -326,7 +328,7 @@ def magic_python_error(self, parameter_s=''):
     global _PYTHON_ERR
     err_info = self.user_ns.get(_PYTHON_ERR)
     if err_info is None:
-        print "No error reported so far."
+        print("No error reported so far.")
         return
     ip = IPython.ipapi.get()
     etype, evalue, etb = err_info[:3]
@@ -336,15 +338,8 @@ _EVT_LOG = None
 def __get_event_log():
     global _EVT_LOG
     if _EVT_LOG is None:
-        qthreads = IPython.ipapi.get().options.q4thread
-        if qthreads:
-            import ipy_qt
-            model = ipy_qt.EventLoggerTableModel(capacity=10000)
-            _EVT_LOG = ipy_qt.EventLogger(model=model)
-            _EVT_LOG.setWindowTitle("ITango - Event Logger Table")
-        else:
-            import ipy_cli
-            _EVT_LOG = ipy_cli.EventLogger(capacity=10000)
+        import PyTango.ipython.eventlogger
+        _EVT_LOG = PyTango.ipython.eventlogger.EventLogger(capacity=10000, pager=IPython.genutils.page)
     return _EVT_LOG
 
 def magic_mon(self, parameter_s=''):
@@ -359,12 +354,12 @@ def magic_mon(self, parameter_s=''):
     
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     opts, args = self.parse_options(parameter_s,'adril', mode='list')
     if len(args) > 3:
         raise IPython.ipapi.UsageError("%mon: too many arguments")
-    if opts.has_key('d'):
+    if 'd' in opts:
         try:
             todel = args[0]
         except IndexError:
@@ -378,12 +373,12 @@ def magic_mon(self, parameter_s=''):
                 del subscriptions[attr.lower()]
                 d = __get_device_proxy(dev)
                 d.unsubscribe_event(id)
-                print "Stopped monitoring '%s'" % todel
+                print("Stopped monitoring '%s'" % todel)
             except KeyError:
                 raise IPython.ipapi.UsageError(
                     "%%mon -d: Not monitoring '%s'" % todel)
                     
-    elif opts.has_key('a'):
+    elif 'a' in opts:
         try:
             toadd = args[0]
         except IndexError:
@@ -400,14 +395,14 @@ def magic_mon(self, parameter_s=''):
         model = w.model()
         id = d.subscribe_event(attr, PyTango.EventType.CHANGE_EVENT, model, [])
         subscriptions[attr.lower()] = id
-        print "'%s' is now being monitored. Type 'mon' to see all events" % toadd
-    elif opts.has_key('r'):
+        print("'%s' is now being monitored. Type 'mon' to see all events" % toadd)
+    elif 'r' in opts:
         for d, v in db._db_cache.devices.items():
             d, subs = v[3], v[4]
             for id in subs.values():
                 d.unsubscribe_event(id)
             v[4] = {}
-    elif opts.has_key('i'):
+    elif 'i' in opts:
         try:
             evtid = int(args[0])
         except IndexError:
@@ -420,13 +415,13 @@ def magic_mon(self, parameter_s=''):
             w = __get_event_log()
             e = w.getEvents()[evtid]
             if e.err:
-                print str(PyTango.DevFailed(*e.errors))
+                print(str(PyTango.DevFailed(*e.errors)))
             else:
-                print str(e)
+                print(str(e))
         except IndexError:
             raise IPython.ipapi.UsageError(
                 "%mon -i: must provide a valid event ID")
-    elif opts.has_key('l'):
+    elif 'l' in opts:
         try:
             dexpr = args[0]
             aexpr = args[1]
@@ -455,7 +450,7 @@ def get_device_map():
            DeviceProxy to this device, create your own)"""
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     return db._db_cache.devices
 
@@ -464,7 +459,7 @@ def get_server_map():
     and value is a sequence of device names that belong to the server"""
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     return db._db_cache.servers
 
@@ -473,7 +468,7 @@ def get_class_map():
     sequence of device names that belong to the tango class"""
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     return db._db_cache.klasses
 
@@ -482,7 +477,7 @@ def get_alias_map():
     is a the tango device name"""
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     return db._db_cache.aliases
 
@@ -491,7 +486,7 @@ def get_device_list():
     database"""
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     return db._db_cache.device_list
 
@@ -500,7 +495,7 @@ def get_alias_list():
     database"""
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     return db._db_cache.alias_list    
     
@@ -515,15 +510,15 @@ def __exc_handler(ip, etype, value, tb):
         ip.user_ns[_TANGO_ERR] = etype, value, tb
         if len(value.args):
             v = value[0]
-            print "%s: %s" % (v.reason ,v.desc)
+            print("%s: %s" % (v.reason ,v.desc))
         else:
-            print "Empty DevFailed"
-        print "(For more detailed information type: tango_error)"
+            print("Empty DevFailed")
+        print("(For more detailed information type: tango_error)")
     else:
         global _PYTHON_ERR
         ip.user_ns[_PYTHON_ERR] = etype, value, tb
-        print etype.__name__ + ": " + str(value)
-        print "(For more detailed information type: python_error)"
+        print(etype.__name__ + ": " + str(value))
+        print("(For more detailed information type: python_error)")
 
 def __get_default_tango_host():
     global _DFT_TANGO_HOST
@@ -575,15 +570,15 @@ def __get_db(host_port=None):
             
             ip.user_ns["DB_NAME"] = host_port
         except Exception:
-            print
+            print()
             if db:
-                print "Could not access Database", host_port
+                print("Could not access Database", host_port)
                 old_host_port = "%s:%s" % (db.get_db_host(), db.get_db_port())
-                print "Maintaining connection to Database", old_host_port
+                print("Maintaining connection to Database", old_host_port)
                 ip.user_ns["DB_NAME"] = old_host_port
             else:
-                print "Could not access any Database."
-                print "Make sure .tangorc, /etc/tangorc or TANGO_HOST environment is defined."
+                print("Could not access any Database.")
+                print("Make sure .tangorc, /etc/tangorc or TANGO_HOST environment is defined.")
                 ip.user_ns["DB_NAME"] = "OFFLINE"
                 
         # register the 'db' in the user namespace
@@ -605,16 +600,16 @@ def __completer_wrapper(f):
     def wrapper(ip, evt):
         try:
             return f(ip, evt)
-        except Exception, e:
-            print
-            print "An unexpected exception ocorred during ITango command completer."
-            print "Please send a bug report to the PyTango team with the following informantion:"
-            print IPython.ipapi.get().options.banner
-            print 80*"-"
-            print "Completer:",__get_obj_name(f)
-            print 80*"-"
-            print str(e)
-            print 80*"-"
+        except Exception as e:
+            print()
+            print("An unexpected exception ocorred during ITango command completer.")
+            print("Please send a bug report to the PyTango team with the following informantion:")
+            print(IPython.ipapi.get().options.banner)
+            print(80*"-")
+            print("Completer:",__get_obj_name(f))
+            print(80*"-")
+            print(str(e))
+            print(80*"-")
             raise e
     return wrapper
 
@@ -693,7 +688,7 @@ def __store(ip, var):
     # we hide the standard output 
     stdout = sys.stdout
     try:
-        sys.stdout = StringIO.StringIO()
+        sys.stdout = io.BytesIO()
         ip.magic("store %s" % var)
     finally:
         sys.stdout = stdout
@@ -773,7 +768,7 @@ def init_db(ip, parameter_s=''):
         
     if db is None: return
     
-    os.environ["TANGO_HOST"] = "%s:%s" % (db.get_db_host(), db.get_db_port())
+    #os.environ["TANGO_HOST"] = "%s:%s" % (db.get_db_host(), db.get_db_port())
     
     # Initialize device and server information
     query = "SELECT name, alias, server, class FROM device order by name"
@@ -818,7 +813,7 @@ def init_db(ip, parameter_s=''):
     excluded_klasses = "DServer",
     for klass, devices in klass_dict.items():
         if klass in excluded_klasses: continue
-        if not ip.user_ns.has_key(klass) or klass in old_junk:
+        if klass not in ip.user_ns or klass in old_junk:
             c = DeviceClassCompleter(klass, devices)
             ip.set_hook('complete_command', c, re_key = ".*" + klass + "[^\w\.]+")
             exposed_klasses[klass] = PyTango.DeviceProxy
@@ -872,7 +867,7 @@ def init_store(ip):
     tango_store = ip.user_ns.get(_TANGO_STORE)
     
     if tango_store is None:
-        print "Initializing tango store (should only happen once)"
+        print("Initializing tango store (should only happen once)")
         tango_store = {}
         ip.to_user_ns( { _TANGO_STORE : tango_store} )
         __store(ip, _TANGO_STORE)
@@ -895,8 +890,8 @@ def init_console(ip):
 
     so = ip.user_ns.get("tango_options", so)
     
-    o.colors = "Tango"
-    o.prompt_in1 = "ITango <$DB_NAME> [\\#]: "
+    #o.colors = "Tango"
+    o.prompt_in1 = "ITango [\\#]: "
     o.prompt_out = "Result [\\#]: "
     banner = """
 %(Purple)sITango %(version)s%(Normal)s -- An interactive %(Purple)sTango%(Normal)s client.
@@ -971,3 +966,18 @@ def init_ipython(ip, store=True, pytango=True, colors=True, console=True, magic=
     if magic:   init_magic(ip)
     
     _tango_init = True
+
+def run():
+    argv = sys.argv
+
+    try:
+        for i, arg in enumerate(argv[:1]):
+            if arg.startswith('--profile='):
+                break
+        else:
+            argv.append("--profile=tango")
+    except:
+        pass    
+        
+    shell = IPython.Shell.start()
+    shell.mainloop()
diff --git a/PyTango/ipython/ipython_00_11/__init__.py b/PyTango/ipython/ipython_00_11/__init__.py
index 5e43cec..443c485 100644
--- a/PyTango/ipython/ipython_00_11/__init__.py
+++ b/PyTango/ipython/ipython_00_11/__init__.py
@@ -22,8 +22,8 @@
 ################################################################################
 
 __all__ = ['load_ipython_extension', 'unload_ipython_extension', 'load_config',
-           'install']
+           'run', 'install', 'is_installed']
 
-from ipython_00_11 import load_ipython_extension, unload_ipython_extension, \
-    load_config
-from ipy_install import install
\ No newline at end of file
+from .ipython_00_11 import load_ipython_extension, unload_ipython_extension, \
+    load_config, run
+from .ipy_install import install, is_installed
diff --git a/PyTango/ipython/ipython_00_11/ipy_install.py b/PyTango/ipython/ipython_00_11/ipy_install.py
index fe967af..8db8d73 100644
--- a/PyTango/ipython/ipython_00_11/ipy_install.py
+++ b/PyTango/ipython/ipython_00_11/ipy_install.py
@@ -27,7 +27,7 @@ from __future__ import with_statement
 
 import sys
 import os
-import StringIO
+import io
 
 import IPython
 from IPython.core.profiledir import ProfileDirError, ProfileDir
@@ -51,11 +51,21 @@ PyTango.ipython.load_config(config)
 # Put any additional environment here
 """
 
+def is_installed(ipydir=None, profile='tango'):
+    ipython_dir = ipydir or get_ipython_dir()
+    try:
+        p_dir = ProfileDir.find_profile_dir_by_name(ipython_dir, profile)
+    except ProfileDirError:
+        return False
+    config_file_name = BaseIPythonApplication.config_file_name.default_value
+    abs_config_file_name = os.path.join(p_dir.location, config_file_name)
+    return os.path.isfile(abs_config_file_name)
+
 def install(ipydir=None, verbose=True, profile='tango'):
     if verbose:
         out = sys.stdout
     else:
-        out = StringIO.StringIO()
+        out = io.StringIO()
     
     ipython_dir = ipydir or get_ipython_dir()
     try:
@@ -73,16 +83,16 @@ def install(ipydir=None, verbose=True, profile='tango'):
     if not create_config:
         return
 
-    out.write("Installing tango extension to ipython... ")
+    out.write(u"Installing tango extension to ipython... ")
     out.flush()
 
     profile = __PROFILE.format(pytangover=PyTango.Release.version,
                                ipyver=IPython.release.version)
-    with file(abs_config_file_name, "w") as f:
+    with open(abs_config_file_name, "w") as f:
         f.write(profile)
         f.close()
-    out.write("[DONE]\n\n")
-    out.write("""\
+    out.write(u"[DONE]\n\n")
+    out.write(u"""\
 To start ipython with tango interface simply type on the command line:
 %% ipython --profile=tango
 
diff --git a/PyTango/ipython/ipython_00_11/ipython_00_11.py b/PyTango/ipython/ipython_00_11/ipython_00_11.py
index 669a2a4..e3ec782 100644
--- a/PyTango/ipython/ipython_00_11/ipython_00_11.py
+++ b/PyTango/ipython/ipython_00_11/ipython_00_11.py
@@ -25,23 +25,29 @@
 
 """An IPython profile designed to provide a user friendly interface to Tango"""
 
+from __future__ import print_function
+
 __all__ = ["load_config", "load_ipython_extension", "unload_ipython_extension"]
 
 import sys
 import os
 import re
-import StringIO
+import io
+import operator
 import textwrap
 
-from IPython.core import ipapi
 from IPython.core.error import UsageError
 from IPython.utils.ipstruct import Struct
 from IPython.core.page import page
+from IPython.core.interactiveshell import InteractiveShell
+from IPython.config.application import Application
+from IPython.frontend.terminal.ipapp import launch_new_instance
 
 import PyTango
 import PyTango.utils
 
-_TG_EXCEPTIONS = PyTango.DevFailed, PyTango.CommunicationFailed, \
+_TG_EXCEPTIONS = PyTango.DevFailed, PyTango.ConnectionFailed, \
+    PyTango.CommunicationFailed, \
     PyTango.NamedDevFailed, PyTango.NamedDevFailedList, \
     PyTango.WrongNameSyntax, PyTango.NonDbDevice, PyTango.WrongData, \
     PyTango.NonSupportedFeature, PyTango.AsynCall, \
@@ -55,6 +61,37 @@ _TANGO_ERR = "__tango_error"
 _PYTHON_ERR = "__python_error"
 _tango_init = False
 
+#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
+# IPython utilities
+#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
+
+def get_pylab_mode():
+    return get_app().pylab
+
+def get_color_mode():
+    return get_config().InteractiveShell.colors
+
+def get_app():
+    #return TerminalIPythonApp.instance()
+    return Application.instance()
+
+def get_shell():
+    """Get the global InteractiveShell instance."""
+    return get_app().shell
+
+def get_ipapi():
+    """Get the global InteractiveShell instance."""
+    return InteractiveShell.instance()
+
+def get_config():
+    return get_app().config
+
+def get_editor():
+    return get_ipapi().editor
+
+def get_user_ns():
+    return get_shell().user_ns
+
 class DeviceClassCompleter(object):
     """Completer class that returns the list of devices of some class when
     called. """
@@ -172,7 +209,7 @@ def __AttributeProxy_completer(ip, evt):
 def __get_device_proxy(dev_name):
     db = __get_db()
     if db is None: return
-    cache = db._db_cacheIPyh
+    cache = db._db_cache
     from_alias = cache.aliases.get(dev_name)
     
     if from_alias is not None:
@@ -207,10 +244,10 @@ __monitor_completer = __AttributeProxy_completer
 # Magic commands
 #-------------------------------------------------------------------------------
 
-def magic_refreshdb(self, parameter_s=''):
-    init_db(ipapi.get(), parameter_s)
+def refreshdb(self, parameter_s=''):
+    init_db(parameter_s)
 
-def magic_switchdb(self, parameter_s=''):
+def switchdb(self, parameter_s=''):
     """Switches the active tango Database.
     
     Usage: switchdb <host>[(:| )<port>]
@@ -225,9 +262,9 @@ def magic_switchdb(self, parameter_s=''):
     if parameter_s == '':
         raise UsageError("%switchdb: Must specify a tango database name. "\
                          "See '%switchdb?'")
-    return init_db(ipapi.get(), parameter_s)
+    return init_db(parameter_s)
 
-def magic_lsdev(self, parameter_s=''):
+def lsdev(self, parameter_s=''):
     """Lists all known tango devices.
     
     Usage: lsdev [<device name filter(regular expression)]
@@ -243,22 +280,25 @@ def magic_lsdev(self, parameter_s=''):
     
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database. Device list is empty"
+        print("You are not connected to any Tango Database. Device list is empty")
         return
     data = db._db_cache.devices
 
-    s = StringIO.StringIO()
-    cols = 40, 25, 25, 20
-    l = "%{0}s %{1}s %{2}s %{3}s".format(*cols)
-    print >>s, l % ("Device", "Alias", "Server", "Class")
-    print >>s, l % (cols[0]*"-", cols[1]*"-", cols[2]*"-", cols[3]*"-")
+    s = io.BytesIO()
+    lengths = 40, 25, 25, 20
+    title = "Device", "Alias", "Server", "Class"
+    templ = "{0:{l[0]}} {1:{l[1]}} {2:{l[2]}} {3:{l[3]}}"
+    msg = templ.format(*title, l=lengths)
+    print(msg, file=s)
+    print(*map(operator.mul, lengths, len(lengths)*"-"), file=s)
     for d, v in data.items():
-        if reg_exp and not reg_exp.match(d): continue
-        print >>s, l % (d, v[0], v[1], v[2])
+        if reg_exp and not reg_exp.match(d):
+            continue
+        print(templ.format(d, v[0], v[1], v[2], l=lengths), file=s)
     s.seek(0)
     page(s.read())
 
-def magic_lsdevclass(self, parameter_s=''):
+def lsdevclass(self, parameter_s=''):
     """Lists all known tango device classes.
     
     Usage: lsdevclass [<class name filter(regular expression)]
@@ -274,16 +314,16 @@ def magic_lsdevclass(self, parameter_s=''):
     
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database. Device class list is empty"
+        print("You are not connected to any Tango Database. Device class list is empty")
         return
     data = db._db_cache.klasses
 
-    s = StringIO.StringIO()
+    s = io.BytesIO()
     data = [ "%-030s" % klass for klass in data.keys() if not reg_exp or reg_exp.match(klass) ]
     s = textwrap.fill(" ".join(data), 80)
     page(s)
 
-def magic_lsserv(self, parameter_s=''):
+def lsserv(self, parameter_s=''):
     """Lists all known tango servers.
     
     Usage: lsserv [<class name filter(regular expression)]
@@ -299,35 +339,33 @@ def magic_lsserv(self, parameter_s=''):
     
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database. Device class list is empty"
+        print("You are not connected to any Tango Database. Device class list is empty")
         return
     data = db._db_cache.servers
 
-    s = StringIO.StringIO()
+    s = io.BytesIO()
     data = [ "%-030s" % server for server in data.keys() if not reg_exp or reg_exp.match(server) ]
     s = textwrap.fill(" ".join(data), 80)
     page(s)
 
-def magic_tango_error(self, parameter_s=''):
+def tango_error(self, parameter_s=''):
     """Displays detailed information about the last tango error"""
-    
     global _TANGO_ERR
-    err_info = self.user_ns.get(_TANGO_ERR)
+    err_info = get_user_ns().get(_TANGO_ERR)
     if err_info is None:
-        print "No tango error reported so far."
+        print("No tango error reported so far.")
         return
-    print "Last tango error:"
-    print err_info[1]
+    print("Last tango error:")
+    print(err_info[1])
 
-def magic_python_error(self, parameter_s=''):
+def python_error(self, parameter_s=''):
     """Displays detailed information about the last python error"""
-    
     global _PYTHON_ERR
-    err_info = self.user_ns.get(_PYTHON_ERR)
+    err_info = get_user_ns().get(_PYTHON_ERR)
     if err_info is None:
-        print "No error reported so far."
+        print("No error reported so far.")
         return
-    ip = ipapi.get()
+    ip = get_ipapi()
     etype, evalue, etb = err_info[:3]
     ip.InteractiveTB(etype=etype, evalue=evalue, etb=etb, tb_offset=None)
 
@@ -335,18 +373,18 @@ _EVT_LOG = None
 def __get_event_log():
     global _EVT_LOG
     if _EVT_LOG is None:
-        qthreads = ipapi.get().options.q4thread
-        if qthreads:
-            import ipy_qt
-            model = ipy_qt.EventLoggerTableModel(capacity=10000)
-            _EVT_LOG = ipy_qt.EventLogger(model=model)
-            _EVT_LOG.setWindowTitle("ITango - Event Logger Table")
-        else:
-            import ipy_cli
-            _EVT_LOG = ipy_cli.EventLogger(capacity=10000)
+#        qthreads = get_config().q4thread
+#        if qthreads:
+#            import ipy_qt
+#            model = ipy_qt.EventLoggerTableModel(capacity=10000)
+#            _EVT_LOG = ipy_qt.EventLogger(model=model)
+#            _EVT_LOG.setWindowTitle("ITango - Event Logger Table")
+#        else:
+        import PyTango.ipython.eventlogger
+        _EVT_LOG = PyTango.ipython.eventlogger.EventLogger(capacity=10000, pager=page)
     return _EVT_LOG
 
-def magic_mon(self, parameter_s=''):
+def mon(self, parameter_s=''):
     """Monitor a given attribute.
     
     %mon -a <attribute name>           - activates monitoring of given attribute
@@ -358,12 +396,15 @@ def magic_mon(self, parameter_s=''):
     
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
+    
+    # make sure parameter_s is a str and not a unicode
+    parameter_s = str(parameter_s)
     opts, args = self.parse_options(parameter_s,'adril', mode='list')
     if len(args) > 3:
         raise UsageError("%mon: too many arguments")
-    if opts.has_key('d'):
+    if 'd' in opts:
         try:
             todel = args[0]
         except IndexError:
@@ -376,11 +417,11 @@ def magic_mon(self, parameter_s=''):
                 del subscriptions[attr.lower()]
                 d = __get_device_proxy(dev)
                 d.unsubscribe_event(id)
-                print "Stopped monitoring '%s'" % todel
+                print("Stopped monitoring '%s'" % todel)
             except KeyError:
                 raise UsageError("%%mon -d: Not monitoring '%s'" % todel)
                     
-    elif opts.has_key('a'):
+    elif 'a' in opts:
         try:
             toadd = args[0]
         except IndexError:
@@ -395,14 +436,14 @@ def magic_mon(self, parameter_s=''):
         model = w.model()
         id = d.subscribe_event(attr, PyTango.EventType.CHANGE_EVENT, model, [])
         subscriptions[attr.lower()] = id
-        print "'%s' is now being monitored. Type 'mon' to see all events" % toadd
-    elif opts.has_key('r'):
+        print("'%s' is now being monitored. Type 'mon' to see all events" % toadd)
+    elif 'r' in opts:
         for d, v in db._db_cache.devices.items():
             d, subs = v[3], v[4]
             for id in subs.values():
                 d.unsubscribe_event(id)
             v[4] = {}
-    elif opts.has_key('i'):
+    elif 'i' in opts:
         try:
             evtid = int(args[0])
         except IndexError:
@@ -413,12 +454,12 @@ def magic_mon(self, parameter_s=''):
             w = __get_event_log()
             e = w.getEvents()[evtid]
             if e.err:
-                print str(PyTango.DevFailed(*e.errors))
+                print(str(PyTango.DevFailed(*e.errors)))
             else:
-                print str(e)
+                print(str(e))
         except IndexError:
             raise UsageError("%mon -i: must provide a valid event ID")
-    elif opts.has_key('l'):
+    elif 'l' in opts:
         try:
             dexpr = args[0]
             aexpr = args[1]
@@ -447,7 +488,7 @@ def get_device_map():
            DeviceProxy to this device, create your own)"""
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     return db._db_cache.devices
 
@@ -456,7 +497,7 @@ def get_server_map():
     and value is a sequence of device names that belong to the server"""
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     return db._db_cache.servers
 
@@ -465,7 +506,7 @@ def get_class_map():
     sequence of device names that belong to the tango class"""
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     return db._db_cache.klasses
 
@@ -474,7 +515,7 @@ def get_alias_map():
     is a the tango device name"""
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     return db._db_cache.aliases
 
@@ -483,7 +524,7 @@ def get_device_list():
     database"""
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     return db._db_cache.device_list
 
@@ -492,7 +533,7 @@ def get_alias_list():
     database"""
     db = __get_db()
     if db is None:
-        print "You are not connected to any Tango Database."
+        print("You are not connected to any Tango Database.")
         return
     return db._db_cache.alias_list    
     
@@ -502,20 +543,21 @@ def get_alias_list():
 
 def __exc_handler(ip, etype, value, tb, tb_offset=None):
     global _TG_EXCEPTIONS
+    user_ns = get_user_ns()
     if etype in _TG_EXCEPTIONS:
         global _TANGO_ERR
-        ip.user_ns[_TANGO_ERR] = etype, value, tb, tb_offset
+        user_ns[_TANGO_ERR] = etype, value, tb, tb_offset
         if len(value.args):
             v = value[0]
-            print "%s: %s" % (v.reason ,v.desc)
+            print("%s: %s" % (v.reason ,v.desc))
         else:
-            print "Empty DevFailed"
-        print "(For more detailed information type: tango_error)"
+            print("Empty DevFailed")
+        print("(For more detailed information type: tango_error)")
     else:
         global _PYTHON_ERR
-        ip.user_ns[_PYTHON_ERR] = etype, value, tb, tb_offset
-        print etype.__name__ + ": " + str(value)
-        print "(For more detailed information type: python_error)"
+        user_ns[_PYTHON_ERR] = etype, value, tb, tb_offset
+        print(etype.__name__ + ": " + str(value))
+        print("(For more detailed information type: python_error)")
 
 def __get_default_tango_host():
     global _DFT_TANGO_HOST
@@ -536,9 +578,11 @@ def __get_db(host_port=None):
                           and return it
     """
     
-    ip = ipapi.get()
+    ip = get_ipapi()
+    user_ns = get_user_ns()
+
     global _DB_SYMB
-    db = ip.user_ns.get(_DB_SYMB)
+    db = user_ns.get(_DB_SYMB)
     
     if host_port is None:
         if db is None:
@@ -565,22 +609,22 @@ def __get_db(host_port=None):
         try:
             db = PyTango.Database(*host_port.split(":"))
             
-            ip.user_ns["DB_NAME"] = host_port
-        except Exception, e:
+            user_ns["DB_NAME"] = host_port
+        except Exception as e:
             if db:
-                print "\nCould not access Database %s:" % host_port
-                print str(e)
+                print("\nCould not access Database %s:" % host_port)
+                print(str(e))
                 old_host_port = "%s:%s" % (db.get_db_host(), db.get_db_port())
-                print "Maintaining connection to Database", old_host_port
-                ip.user_ns["DB_NAME"] = old_host_port
+                print("Maintaining connection to Database", old_host_port)
+                user_ns["DB_NAME"] = old_host_port
             else:
-                print "\nCould not access any Database. Make sure:"
-                print "\t- .tangorc, /etc/tangorc or TANGO_HOST environment is defined."
-                print "\t- the Database DS is running"
-                ip.user_ns["DB_NAME"] = "OFFLINE"
+                print("\nCould not access any Database. Make sure:")
+                print("\t- .tangorc, /etc/tangorc or TANGO_HOST environment is defined.")
+                print("\t- the Database DS is running")
+                user_ns["DB_NAME"] = "OFFLINE"
                 
         # register the 'db' in the user namespace
-        ip.user_ns.update({ _DB_SYMB : db })
+        user_ns.update({ _DB_SYMB : db })
         
     return db
 
@@ -598,16 +642,16 @@ def __completer_wrapper(f):
     def wrapper(ip, evt):
         try:
             return f(ip, evt)
-        except Exception, e:
-            print
-            print "An unexpected exception ocorred during ITango command completer."
-            print "Please send a bug report to the PyTango team with the following information:"
-            print 80*"-"
-            print "Completer:",__get_obj_name(f)
-            print 80*"-"
+        except Exception as e:
+            print()
+            print("An unexpected exception ocorred during ITango command completer.")
+            print("Please send a bug report to the PyTango team with the following information:")
+            print(80*"-")
+            print("Completer:",__get_obj_name(f))
+            print(80*"-")
             import traceback
             traceback.print_exc()
-            print 80*"-"
+            print(80*"-")
             raise e
     return wrapper
 
@@ -621,7 +665,7 @@ def __expose_magic(ip, name, fn, completer_func=None):
     ip.set_hook('complete_command', completer_func, re_key = ".*" + name)
 
 def __unexpose_magic(ip, name):
-    delattr(ip, 'magic_' + name)
+    delattr(ip, name)
 
 def __build_color_scheme(ip, name):
     import IPython.Prompts
@@ -687,16 +731,18 @@ def init_pytango(ip):
     
     ip.set_custom_exc((Exception,), __exc_handler)
 
-def init_db(ip, parameter_s=''):
+def init_db(parameter_s=''):
+    ip = get_ipapi()
+    user_ns = get_user_ns()
     global _DB_SYMB
-    old_db = ip.user_ns.get(_DB_SYMB)
+    old_db = user_ns.get(_DB_SYMB)
     
     db = __get_db(parameter_s)
     
     if old_db is not None and hasattr(old_db, "_db_cache"):
         old_junk = old_db._db_cache["junk"].keys()
         for e in old_junk:
-            del ip.user_ns[e]
+            del user_ns[e]
     else:
         old_junk = ()
         
@@ -748,14 +794,14 @@ def init_db(ip, parameter_s=''):
     for klass, devices in klass_dict.items():
         if klass in excluded_klasses:
             continue
-        exists = ip.user_ns.has_key(klass)
+        exists = klass in user_ns
         if not exists or klass in old_junk:
             c = DeviceClassCompleter(klass, devices)
             ip.set_hook('complete_command', c, re_key = ".*" + klass + "[^\w\.]+")
             exposed_klasses[klass] = PyTango.DeviceProxy
     
     # expose classes no user namespace
-    ip.user_ns.update(exposed_klasses)
+    user_ns.update(exposed_klasses)
     
     # Initialize attribute information
     query = "SELECT name, alias FROM attribute_alias order by alias"
@@ -791,34 +837,46 @@ def init_db(ip, parameter_s=''):
     return db
 
 def init_magic(ip):
-    __expose_magic(ip, "refreshdb", magic_refreshdb)
-    __expose_magic(ip, "reloaddb", magic_refreshdb)
-    __expose_magic(ip, "switchdb", magic_switchdb)
-    __expose_magic(ip, "lsdev", magic_lsdev)
-    __expose_magic(ip, "lsdevclass", magic_lsdevclass)
-    __expose_magic(ip, "lsserv", magic_lsserv)
-    __expose_magic(ip, "tango_error", magic_tango_error)
-    __expose_magic(ip, "python_error", magic_python_error)
-    __expose_magic(ip, "mon", magic_mon, __monitor_completer)
-    #__expose_magic(ip, "umon", magic_umon, __monitor_completer)
-    
-    ip.user_ns.update({"get_device_map"   : get_device_map,
+
+    import IPython.core.magic
+
+    new_style_magics = hasattr(IPython.core.magic, 'Magics') and hasattr(IPython.core.magic, 'magics_class')
+
+    if new_style_magics:
+        @IPython.core.magic.magics_class
+        class Tango(IPython.core.magic.Magics):
+            
+            refreshdb = IPython.core.magic.line_magic(refreshdb)
+            switchdb = IPython.core.magic.line_magic(switchdb)
+            lsdev = IPython.core.magic.line_magic(lsdev)
+            lsdevclass = IPython.core.magic.line_magic(lsdevclass)
+            lsserv = IPython.core.magic.line_magic(lsserv)
+            tango_error = IPython.core.magic.line_magic(tango_error)
+            python_error = IPython.core.magic.line_magic(python_error)
+            mon = IPython.core.magic.line_magic(mon)
+
+        ip.register_magics(Tango)
+        ip.set_hook('complete_command', __monitor_completer, re_key = ".*" + "mon")
+    else:
+        __expose_magic(ip, "refreshdb", refreshdb)
+        __expose_magic(ip, "switchdb", switchdb)
+        __expose_magic(ip, "lsdev", lsdev)
+        __expose_magic(ip, "lsdevclass", lsdevclass)
+        __expose_magic(ip, "lsserv", lsserv)
+        __expose_magic(ip, "tango_error", tango_error)
+        __expose_magic(ip, "python_error", python_error)
+        __expose_magic(ip, "mon", mon, __monitor_completer)
+    
+    get_user_ns().update({"get_device_map"   : get_device_map,
                    "get_server_map"  : get_server_map,
                    "get_class_map"   : get_class_map,
                    "get_alias_map"   : get_alias_map,
                    "get_device_list" : get_device_list,
                    "get_alias_list"  : get_alias_list})
-    
-    #__expose_magic(ip, "get_device_map", get_device_map)
-    #__expose_magic(ip, "get_server_map", get_server_map)
-    #__expose_magic(ip, "get_class_map", get_class_map)
-    #__expose_magic(ip, "get_alias_map", get_alias_map)
-    #__expose_magic(ip, "get_device_list", get_device_list)
-    #__expose_magic(ip, "get_alias_list", get_alias_list)
 
 def complete(text):
     """a super complete!!!!"""
-    self = ipapi.get().IP
+    self = get_ipapi().IP
     complete = self.Completer.complete
     state = 0
     comps = set()
@@ -831,19 +889,262 @@ def complete(text):
     outcomps = sorted(comps)
     return outcomps
 
+__DIRNAME = os.path.dirname(os.path.abspath(__file__))
+__RES_DIR = os.path.join(__DIRNAME, os.path.pardir, 'resource')
+
+class __TangoInfo(object):
+    """Helper class for when DeviceProxy.info() is not available"""
+    
+    def __init__(self, dev):
+        try:
+            db = dev.get_device_db()
+            klass = db.get_class_for_device(dev.dev_name())
+            self.dev_class = self.dev_type = klass
+        except:
+            self.dev_class = self.dev_type = 'Device'
+        self.doc_url = 'http://www.esrf.eu/computing/cs/tango/tango_doc/ds_doc/index.html'
+        self.server_host = 'Unknown'
+        self.server_id = 'Unknown'
+        self.server_version = 1
+
+def __get_device_icon(dev_proxy, klass="Device"):
+    icon_prop = "__icon"
+    db = dev_proxy.get_device_db()
+    try:
+        icon_filename = dev_proxy.get_property(icon_prop)[icon_prop]
+        if icon_filename:
+            icon_filename = icon_filename[0]
+        else:
+            icon_filename = db.get_class_property(klass, icon_prop)[icon_prop]
+            if icon_filename:
+                icon_filename = icon_filename[0]
+            else:            
+                icon_filename = klass.lower() + os.path.extsep + "png"
+    except:
+        icon_filename = klass.lower() + os.path.extsep + "png"
+    
+    if os.path.isabs(icon_filename):
+        icon = icon_filename
+    else:
+        icon = os.path.join(__RES_DIR, icon_filename)
+    if not os.path.isfile(icon):
+        icon = os.path.join(__RES_DIR, "device.png")
+    return icon
+
+__DEV_HTML_TEMPLATE = """\
+<table border="0" cellpadding="2" width="100%">
+<tr><td width="140" rowspan="7" valign="middle" align="center"><img src="{icon}" height="128"/></td>
+    <td width="140">Name:</td><td><b>{name}</b></td></tr>
+<tr><td width="140">Alias:</td><td>{alias}</td></tr>
+<tr><td width="140">Database:</td><td>{database}</td></tr>
+<tr><td width="140">Type:</td><td>{dev_class}</td></tr>
+<tr><td width="140">Server:</td><td>{server_id}</td></tr>
+<tr><td width="140">Server host:</td><td>{server_host}</td></tr>
+<tr><td width="140">Documentation:</td><td><a target="_blank" href="{doc_url}">{doc_url}</a></td></tr>
+</table>"""
+
+def display_deviceproxy_html(dev_proxy):
+    """displayhook function for PyTango.DeviceProxy, rendered as HTML"""
+    try:
+        info = dev_proxy.info()
+    except:
+        info = __TangoInfo(dev_proxy)
+    name = dev_proxy.dev_name()
+    fmt = dict(dev_class=info.dev_class, server_id=info.server_id,
+               server_host=info.server_host, name=name)
+    
+    try:
+        fmt["alias"] = dev_proxy.alias()
+    except:
+        fmt["alias"] = "-----"
+
+    db = dev_proxy.get_device_db()
+    try:
+        fmt["database"] = db.get_db_host() + ":" + db.get_db_port()
+    except:
+        try:
+            fmt["database"] = db.get_file_name()
+        except:
+            fmt["database"]  = "Unknown"
+
+    doc_url = info.doc_url.split("\n")[0]
+    try:
+        fmt["doc_url"] = doc_url[doc_url.index("http"):]
+    except ValueError:
+        fmt["doc_url"] = doc_url
+
+    fmt['icon'] = __get_device_icon(dev_proxy, info.dev_class)
+
+    return __DEV_HTML_TEMPLATE.format(**fmt)
+
+__DB_HTML_TEMPLATE = """\
+<table border="0" cellpadding="2" width="100%">
+<tr><td width="140" rowspan="2" valign="middle" align="center"><img src="{icon}" height="128"/></td>
+    <td><b>{name}</b></td></tr>
+<tr><td>{info}</td></tr>
+</table>"""
+
+def display_database_html(db):
+    """displayhook function for PyTango.Database, rendered as HTML"""
+    fmt = dict()
+
+    try:
+        fmt["name"] = db.get_db_host() + ":" + db.get_db_port()
+    except:
+        try:
+            fmt["name"] = db.get_file_name()
+        except:
+            fmt["name"]  = "Unknown"
+
+    try:
+        fmt["info"] = db.get_info().replace("\n", "<BR/>")
+    except:
+        fmt["info"] = "Unknown"
+    
+    fmt['icon'] = os.path.join(__RES_DIR, "database.png")
+
+    return __DB_HTML_TEMPLATE.format(**fmt)
+
+__DEV_ATTR_RW_HTML_TEMPLATE = """\
+<table border="0" cellpadding="2" width="100%">
+<tr><td colspan="2" bgcolor="{bgcolor}">{name} ({type}, {data_format}, {quality}) at {time}</td></tr>
+<tr><td bgcolor="#EEEEEE" width="140">value{r_dim}:</td>
+    <td bgcolor="#EEEEEE">{value}</td></tr>
+<tr><td bgcolor="#EEEEEE" width="140">w_value{w_dim}:</td>
+    <td bgcolor="#EEEEEE">{w_value}</td></tr>
+</table>"""
+
+__DEV_ATTR_RO_HTML_TEMPLATE = """\
+<table border="0" cellpadding="2" width="100%">
+<tr><td colspan="2" bgcolor="{bgcolor}">{name} ({type}, {data_format}, {quality}) at {time}</td></tr>
+<tr><td bgcolor="#EEEEEE" width="140">value{r_dim}:</td>
+    <td bgcolor="#EEEEEE">{value}</td></tr>
+</table>"""
+
+__DEV_ATTR_ERR_HTML_TEMPLATE = """\
+<table border="0" cellpadding="2" width="100%">
+<tr><td bgcolor="#FF0000">{name} ({type}, {data_format}, {quality}) at {time}</td></tr>
+<tr><td bgcolor="#EEEEEE">{error}</td></tr>
+</table>"""
+
+QUALITY_TO_HEXCOLOR_STR = {
+    PyTango.AttrQuality.ATTR_VALID : ("#00FF00", "#000000"),
+    PyTango.AttrQuality.ATTR_INVALID : ("#808080", "#FFFFFF"),    
+    PyTango.AttrQuality.ATTR_ALARM : ("#FF8C00", "#FFFFFF"),    
+    PyTango.AttrQuality.ATTR_WARNING : ("#FF8C00", "#FFFFFF"),    
+    PyTango.AttrQuality.ATTR_CHANGING : ("#80A0FF", "#000000"),
+    None : ("#808080", "#000000"), 
+}
+
+def display_deviceattribute_html(da):
+    """displayhook function for PyTango.DeviceAttribute, rendered as HTML"""
+    fmt = dict(name=da.name, type=da.type, data_format=da.data_format)
+    template = None
+    if da.has_failed:
+        fmt['error'] = "\n".join(map(str, da.get_err_stack())).replace("\n", "<br/>")
+        
+        template = __DEV_ATTR_ERR_HTML_TEMPLATE
+    else:
+        rd, wd = da.r_dimension, da.w_dimension
+        if wd.dim_x == 0 and wd.dim_y == 0 and da.w_value is None:
+            template = __DEV_ATTR_RO_HTML_TEMPLATE
+        else:
+            template = __DEV_ATTR_RW_HTML_TEMPLATE
+            fmt['w_value'] = str(da.w_value)
+            if da.data_format == PyTango.AttrDataFormat.SCALAR:
+                fmt['w_dim'] = ""
+            else:
+                fmt['w_dim'] = "<br/>(%d, %d)" % (wd.dim_x, wd.dim_y)
+        fmt['bgcolor'], fmt['fgcolor'] = QUALITY_TO_HEXCOLOR_STR[da.quality]
+        fmt['quality'] = str(da.quality)
+        if da.data_format == PyTango.AttrDataFormat.SCALAR:
+            fmt['r_dim'] = ""
+        else:
+            fmt['r_dim'] = "<br/>(%d, %d)" % (rd.dim_x, rd.dim_y)
+        fmt['value'] = str(da.value)
+        fmt['time'] = str(da.time.todatetime())
+    return template.format(**fmt)
+
+__GROUP_HTML_TEMPLATE = """\
+<table border="0" cellpadding="2" width="100%">
+<tr><td width="100" bgcolor="#EEEEEE">Name:</td><td bgcolor="#EEEEEE">{name}</td></tr>
+<tr><td width="100" bgcolor="#EEEEEE">Size:</td><td bgcolor="#EEEEEE">{size}</td></tr>
+<tr><td width="100" bgcolor="#EEEEEE">Devices:</td><td bgcolor="#EEEEEE">{devices}</td></tr>
+</table>"""
+
+def display_group_html(group):
+    devices = group.get_device_list()
+    devices = ", ".join(devices)
+    fmt=dict(name=group.get_name(), size=group.get_size(), devices=devices) 
+    return __GROUP_HTML_TEMPLATE.format(**fmt)
+
+__GROUP_REPLY_HTML_TEMPLATE = """\
+<table border="0" cellpadding="2" width="100%">
+<tr><td bgcolor="#EEEEEE">{name}</td></tr>
+<tr><td>{data}</td></tr>    
+"""
+
+__GROUP_REPLY_ERR_HTML_TEMPLATE = """\
+<table border="0" cellpadding="2" width="100%">
+<tr><td bgcolor="#FF0000">{name}</td></tr>
+<tr><td bgcolor="#EEEEEE">{error}</td></tr>
+</table>"""
+    
+def display_groupreply_html(gr):
+    fmt = dict(name="%s/%s" % (gr.dev_name(), gr.obj_name()))
+    template = None
+    if gr.has_failed():
+        fmt['error'] = "\n".join(map(str, gr.get_err_stack())).replace("\n", "<br/>")
+        template = __GROUP_REPLY_ERR_HTML_TEMPLATE
+    else:
+        template = __GROUP_REPLY_HTML_TEMPLATE
+        data = gr.get_data()
+        if isinstance(data, PyTango.DeviceAttribute):
+            data = display_deviceattribute_html(data)
+        fmt["data"] = data
+        
+    ret = template.format(**fmt)
+    return ret
+
+def init_display(ip):
+    html_formatter = ip.display_formatter.formatters["text/html"]
+    html_formatter.for_type(PyTango.DeviceProxy, display_deviceproxy_html)
+    html_formatter.for_type(PyTango.Database, display_database_html)
+    html_formatter.for_type(PyTango.DeviceAttribute, display_deviceattribute_html)
+    html_formatter.for_type(PyTango.Group, display_group_html)
+    html_formatter.for_type(PyTango.GroupAttrReply, display_groupreply_html)
+    html_formatter.for_type(PyTango.GroupCmdReply, display_groupreply_html)
+
+from IPython.utils.traitlets import Unicode
+from IPython.frontend.qt.console.rich_ipython_widget import RichIPythonWidget
+
+class ITangoConsole(RichIPythonWidget):
+    
+    banner = Unicode(config=True)
+
+    def _banner_default(self):
+        config = get_config()
+        return config.ITangoConsole.banner
+
+import IPython.frontend.qt.console.qtconsoleapp
+IPythonQtConsoleApp = IPython.frontend.qt.console.qtconsoleapp.IPythonQtConsoleApp
+IPythonQtConsoleApp.widget_factory = ITangoConsole      
+
 def init_ipython(ip=None, store=True, pytango=True, colors=True, console=True,
                  magic=True):
-    
+
     if ip is None:
-        ip = ipapi.get()
+        ip = get_ipapi()
     
     global _tango_init
     if _tango_init is True: return
+
+    init_display(ip)
     
     if pytango:
         init_pytango(ip)
     
-    init_db(ip)
+    init_db()
 
     if magic:
         init_magic(ip)
@@ -861,10 +1162,13 @@ def load_config(config):
     d.update(IPython.utils.coloransi.TermColors.__dict__)
 
     so = Struct(
-        tango_banner="""%(Blue)shint: Try typing: mydev = Device("%(LightBlue)s<tab>%(Normal)s""")
+        tango_banner="""%(Blue)shint: Try typing: mydev = Device("%(LightBlue)s<tab>%(Normal)s\n""")
 
     so = config.get("tango_options", so)
 
+    import PyTango.ipython
+    ipy_ver = PyTango.ipython.get_ipython_version_list()
+    
     # ------------------------------------
     # Application
     # ------------------------------------
@@ -876,8 +1180,19 @@ def load_config(config):
     # ------------------------------------
     i_shell = config.InteractiveShell
     i_shell.colors = 'Linux'
-    i_shell.prompt_in1 = 'ITango <$DB_NAME> [\\#]: '
-    i_shell.prompt_out = 'Result [\\#]: '
+
+    if ipy_ver >= [0, 12]:
+        # ------------------------------------
+        # PromptManager (ipython >= 0.12)
+        # ------------------------------------
+        prompt = config.PromptManager
+        prompt.in_template = 'ITango [\\#]: '
+        prompt.out_template = 'Result [\\#]: '
+    else:
+        # (Deprecated in ipython >= 0.12 use PromptManager.in_template)
+        i_shell.prompt_in1 = 'ITango [\\#]: '
+        # (Deprecated in ipython >= 0.12 use PromptManager.out_template)
+        i_shell.prompt_out = 'Result [\\#]: '
     
     # ------------------------------------
     # InteractiveShellApp
@@ -901,7 +1216,7 @@ def load_config(config):
     #kernel_app = config.IPKernelApp
     ipython_widget = config.IPythonWidget
     ipython_widget.in_prompt  = 'ITango [<span class="in-prompt-number">%i</span>]: '
-    ipython_widget.out_prompt = '   Out [<span class="out-prompt-number">%i</span>]: '
+    ipython_widget.out_prompt = 'Result [<span class="out-prompt-number">%i</span>]: '
     
     #zmq_i_shell = config.ZMQInteractiveShell
     
@@ -922,9 +1237,17 @@ object?   -> Details about 'object'. ?object also works, ?? prints more.
     banner = banner.format(**d)
     tango_banner = so.tango_banner % d
     tango_banner = tango_banner.format(**d)
+    all_banner = "\n".join((banner, tango_banner))
+
     term_i_shell.banner1 = banner
     term_i_shell.banner2 = tango_banner
 
+    # ------------------------------------
+    # FrontendWidget
+    # ------------------------------------
+    frontend_widget = config.ITangoConsole
+    frontend_widget.banner = all_banner
+    
 def load_ipython_extension(ipython):
     # The ``ipython`` argument is the currently active
     # :class:`InteractiveShell` instance that can be used in any way.
@@ -936,3 +1259,19 @@ def unload_ipython_extension(ipython):
     # If you want your extension to be unloadable, put that logic here.
     #print "Unloading PyTango IPython extension"
     pass
+
+def run():
+
+    argv = sys.argv
+
+    try:
+        for i, arg in enumerate(argv[:1]):
+            if arg.startswith('--profile='):
+                break
+        else:
+            argv.append("--profile=tango")
+    except:
+        pass    
+        
+    launch_new_instance()
+    
diff --git a/PyTango/ipython/ipython_00_12/ipython_00_12.py b/PyTango/ipython/ipython_00_12/ipython_00_12.py
deleted file mode 100644
index 6321580..0000000
--- a/PyTango/ipython/ipython_00_12/ipython_00_12.py
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/usr/bin/env python
-
-################################################################################
-##
-## This file is part of PyTango, a python binding for Tango
-## 
-## http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html
-##
-## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
-## 
-## PyTango is free software: you can redistribute it and/or modify
-## it under the terms of the GNU Lesser General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-## 
-## PyTango is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU Lesser General Public License for more details.
-## 
-## You should have received a copy of the GNU Lesser General Public License
-## along with PyTango.  If not, see <http://www.gnu.org/licenses/>.
-##
-################################################################################
-
-"""An IPython profile designed to provide a user friendly interface to Tango"""
-
-__all__ = ["load_config"]
-
-from IPython.utils.ipstruct import Struct
-from  IPython.utils.coloransi import TermColors
-
-def load_config(config):
-    import PyTango.ipython
-    
-    d = { "version" : PyTango.ipython.get_pytango_version(),
-          "pyver" : PyTango.ipython.get_python_version(),
-          "ipyver" : PyTango.ipython.get_ipython_version(),
-          "pytangover" : PyTango.ipython.get_pytango_version(), }
-    d.update(TermColors.__dict__)
-
-    so = Struct(
-        tango_banner="""%(Blue)shint: Try typing: mydev = Device("%(LightBlue)s<tab>%(Normal)s""")
-
-    so = config.get("tango_options", so)
-
-    # ------------------------------------
-    # Application
-    # ------------------------------------
-    app = config.Application
-    app.log_level = 30
-
-    # ------------------------------------
-    # InteractiveShell
-    # ------------------------------------
-    i_shell = config.InteractiveShell
-    i_shell.colors = 'Linux'
-    
-    # ------------------------------------
-    # PromptManager
-    # ------------------------------------
-    prompt = config.PromptManager
-    prompt.in_template = 'ITango {DB_NAME} [\\#]: '
-    #prompt.in2_template = 
-    prompt.out_template = 'Result [\\#]: '
-    
-    # ------------------------------------
-    # InteractiveShellApp
-    # ------------------------------------
-    i_shell_app = config.InteractiveShellApp
-    extensions = getattr(i_shell_app, 'extensions', [])
-    extensions.append('PyTango.ipython')
-    i_shell_app.extensions = extensions
-    i_shell_app.ignore_old_config=True
-    
-    # ------------------------------------
-    # TerminalIPythonApp: options for the IPython terminal (and not Qt Console)
-    # ------------------------------------
-    term_app = config.TerminalIPythonApp
-    term_app.display_banner = True
-    #term_app.nosep = False
-    #term_app.classic = True
-    
-    # ------------------------------------
-    # IPKernelApp: options for the  Qt Console
-    # ------------------------------------
-    #kernel_app = config.IPKernelApp
-    ipython_widget = config.IPythonWidget
-    ipython_widget.in_prompt  = 'ITango [<span class="in-prompt-number">%i</span>]: '
-    ipython_widget.out_prompt = '   Out [<span class="out-prompt-number">%i</span>]: '
-    
-    #zmq_i_shell = config.ZMQInteractiveShell
-    
-    # ------------------------------------
-    # TerminalInteractiveShell
-    # ------------------------------------
-    term_i_shell = config.TerminalInteractiveShell
-    banner = """\
-%(Purple)sITango %(version)s%(Normal)s -- An interactive %(Purple)sTango%(Normal)s client.
-
-Running on top of Python %(pyver)s, IPython %(ipyver)s and PyTango %(pytangover)s
-
-help      -> ITango's help system.
-object?   -> Details about 'object'. ?object also works, ?? prints more.
-"""
-    
-    banner = banner % d
-    banner = banner.format(**d)
-    tango_banner = so.tango_banner % d
-    tango_banner = tango_banner.format(**d)
-    term_i_shell.banner1 = banner
-    term_i_shell.banner2 = tango_banner
\ No newline at end of file
diff --git a/PyTango/log4tango.py b/PyTango/log4tango.py
index e99e3df..a609c88 100644
--- a/PyTango/log4tango.py
+++ b/PyTango/log4tango.py
@@ -127,7 +127,7 @@ class LogIt(object):
             d = args[0]
             if not self.is_enabled(d):
                 return f(*args, **kwargs)
-            in_msg = "-> %s(" % f.func_name
+            in_msg = "-> %s(" % f.__name__
             if self._show_args:
                 in_msg += ", ".join(map(self.__compact, args[1:]))
             if self._show_kwargs:
@@ -139,7 +139,7 @@ class LogIt(object):
             out_msg = ""
             if self._show_ret:
                 out_msg += self.__compact(ret) + " "
-            out_msg += "<- %s()" % f.func_name
+            out_msg += "<- %s()" % f.__name__
             self.get_log_func(d)(out_msg)
             return ret
         return log_stream
diff --git a/PyTango/pytango_init.py b/PyTango/pytango_init.py
index 193880b..eaf6270 100644
--- a/PyTango/pytango_init.py
+++ b/PyTango/pytango_init.py
@@ -29,29 +29,37 @@ __all__ = ['init']
 
 __docformat__ = "restructuredtext"
 
-import attribute_proxy
-import base_types
-import exception
-import callback
-import api_util
-import encoded_attribute
-import connection
-import db
-import device_attribute
-import device_class
-import device_data
-import device_proxy
-import device_server
-import group
-import group_reply
-import group_reply_list
-import pytango_pprint
-import pyutil
-import time_val
+from .attribute_proxy import attribute_proxy_init
+from .base_types import base_types_init
+from .exception import exception_init
+from .callback import callback_init
+from .api_util import api_util_init
+from .encoded_attribute import encoded_attribute_init
+from .connection import connection_init
+from .db import db_init
+from .device_attribute import device_attribute_init
+from .device_class import device_class_init
+from .device_data import device_data_init
+from .device_proxy import device_proxy_init
+from .device_server import device_server_init
+from .group import group_init
+from .group_reply import group_reply_init
+from .group_reply_list import group_reply_list_init
+from .pytango_pprint import pytango_pprint_init
+from .pyutil import pyutil_init
+from .time_val import time_val_init
+from ._PyTango import constants
 
 __INITIALIZED = False
 __DOC = True
 
+def init_constants():
+    
+    tgver = tuple(map(int, constants.TgLibVers.split(".")))
+    tgver_str = "0x%02d%02d%02d00" % (tgver[0], tgver[1], tgver[2])
+    constants.TANGO_VERSION_HEX = int(tgver_str, 16)
+    
+
 def init():
     global __INITIALIZED
     if __INITIALIZED:
@@ -59,26 +67,27 @@ def init():
     
     global __DOC
     doc = __DOC
-    base_types.init(doc=doc)
-    exception.init(doc=doc)
-    callback.init(doc=doc)
-    api_util.init(doc=doc)
-    encoded_attribute.init(doc=doc)
-    connection.init(doc=doc)
-    db.init(doc=doc)
-    device_attribute.init(doc=doc)
-    device_class.init(doc=doc)
-    device_data.init(doc=doc)
-    device_proxy.init(doc=doc)
-    device_server.init(doc=doc)
-    group.init(doc=doc)
-    group_reply.init(doc=doc)
-    group_reply_list.init(doc=doc)
-    pytango_pprint.init(doc=doc)
-    pyutil.init(doc=doc)
-    time_val.init(doc=doc)
+    init_constants()
+    base_types_init(doc=doc)
+    exception_init(doc=doc)
+    callback_init(doc=doc)
+    api_util_init(doc=doc)
+    encoded_attribute_init(doc=doc)
+    connection_init(doc=doc)
+    db_init(doc=doc)
+    device_attribute_init(doc=doc)
+    device_class_init(doc=doc)
+    device_data_init(doc=doc)
+    device_proxy_init(doc=doc)
+    device_server_init(doc=doc)
+    group_init(doc=doc)
+    group_reply_init(doc=doc)
+    group_reply_list_init(doc=doc)
+    pytango_pprint_init(doc=doc)
+    pyutil_init(doc=doc)
+    time_val_init(doc=doc)
     
     # must come last: depends on device_proxy.init()
-    attribute_proxy.init(doc=doc)
+    attribute_proxy_init(doc=doc)
 
     __INITIALIZED = True
diff --git a/PyTango/pytango_pprint.py b/PyTango/pytango_pprint.py
index bcfdc39..16b3f81 100644
--- a/PyTango/pytango_pprint.py
+++ b/PyTango/pytango_pprint.py
@@ -25,13 +25,13 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["pytango_pprint_init"]
 
 __docformat__ = "restructuredtext"
 
 import operator
 
-from _PyTango import (StdStringVector, StdLongVector, CommandInfoList,
+from ._PyTango import (StdStringVector, StdLongVector, CommandInfoList,
     AttributeInfoList, AttributeInfoListEx,
     DeviceDataHistoryList,
     GroupReplyList, GroupAttrReplyList, GroupCmdReplyList,
@@ -42,18 +42,19 @@ from _PyTango import (StdStringVector, StdLongVector, CommandInfoList,
     AttributeEventInfo, AttributeInfoEx,
     DeviceAttribute, DeviceAttributeHistory, DeviceData, DeviceDataHistory,
     DbDatum, DbDevInfo, DbDevImportInfo, DbDevExportInfo, DbServerInfo,
-    GroupElement, GroupReply, GroupAttrReply, GroupCmdReply,
+    GroupReply, GroupAttrReply, GroupCmdReply,
     DevError, EventData, AttrConfEventData, DataReadyEventData,
     TimeVal, DevFailed, CmdArgType)
 
-from device_server import AttributeAlarm, EventProperties
-from device_server import ChangeEventProp, PeriodicEventProp, ArchiveEventProp
-from device_server import AttributeConfig, AttributeConfig_2, AttributeConfig_3
+from .device_server import AttributeAlarm, EventProperties
+from .device_server import ChangeEventProp, PeriodicEventProp, ArchiveEventProp
+from .device_server import AttributeConfig, AttributeConfig_2, AttributeConfig_3
+import collections
 
 def __inc_param(obj, name):
     ret  = not name.startswith('_')
     ret &= not name in ('except_flags',)
-    ret &= not callable(getattr(obj,name))
+    ret &= not isinstance(getattr(obj,name), collections.Callable)
     return ret
 
 def __single_param(obj, param_name, f=repr, fmt='%s = %s'):
@@ -107,7 +108,7 @@ def __registerSeqStr():
         seq.__repr__ = _SeqRepr
 
 def __str__DevFailed(self):
-    if operator.isSequenceType(self.args):
+    if isinstance(self.args, collections.Sequence):
         return 'DevFailed[\n%s]' % '\n'.join(map(str,self.args))
     return 'DevFailed[%s]' % (self.args)
     
@@ -131,7 +132,7 @@ def __registerStructStr():
         AttributeEventInfo, AttributeInfoEx,
         DeviceAttribute, DeviceAttributeHistory, DeviceData, DeviceDataHistory,
         DbDatum, DbDevInfo, DbDevImportInfo, DbDevExportInfo, DbServerInfo,
-        GroupElement, GroupReply, GroupAttrReply, GroupCmdReply,
+        GroupReply, GroupAttrReply, GroupCmdReply,
         DevError, EventData, AttrConfEventData, DataReadyEventData,
         AttributeConfig, AttributeConfig_2, AttributeConfig_3,
         ChangeEventProp, PeriodicEventProp, ArchiveEventProp,
@@ -152,6 +153,6 @@ def __registerStructStr():
 
     DevError.__str__ = __str__DevError
 
-def init(doc=True):
+def pytango_pprint_init(doc=True):
     __registerSeqStr()
     __registerStructStr()
diff --git a/PyTango/pyutil.py b/PyTango/pyutil.py
index 8ead49f..6f71e24 100644
--- a/PyTango/pyutil.py
+++ b/PyTango/pyutil.py
@@ -25,19 +25,19 @@
 This is an internal PyTango module.
 """
 
-__all__ = [ "Util" ]
+__all__ = [ "Util", "pyutil_init" ]
 
 __docformat__ = "restructuredtext"
 
 import os
 import copy
 
-from _PyTango import _Util, Except, DevFailed, DbDevInfo
-from utils import document_method as __document_method
+from ._PyTango import _Util, Except, DevFailed, DbDevInfo
+from .utils import document_method as __document_method
 #from utils import document_static_method as __document_static_method
-from globals import class_list
-from globals import cpp_class_list
-from globals import get_constructed_classes
+from .globals import class_list, cpp_class_list, get_constructed_classes
+import collections
+
 
 def __simplify_device_name(dev_name):
     if dev_name.startswith("tango://"):
@@ -91,7 +91,7 @@ def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
                    device name (str). Default value is None meaning no callback
         
         Return     : None"""
-    if cb is not None and not callable(cb):
+    if cb is not None and not isinstance(cb, collections.Callable):
         Except.throw_exception("PyAPI_InvalidParameter",
             "The optional cb parameter must be a python callable",
             "Util.create_device")
@@ -103,7 +103,7 @@ def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
     device_exists = True
     try:
         db.import_device(device_name)
-    except DevFailed, df:
+    except DevFailed as df:
         device_exists = not df[0].reason == "DB_DeviceNotDefined"
 
     # 1 - Make sure device name doesn't exist already in the database
@@ -177,7 +177,7 @@ def __Util__delete_device(self, klass_name, device_name):
     device_exists = True
     try:
         db.import_device(device_name)
-    except DevFailed, df:
+    except DevFailed as df:
         device_exists = not df[0].reason == "DB_DeviceNotDefined"
 
     # 1 - Make sure device name exists in the database
@@ -220,7 +220,7 @@ class Util(_Util):
         class and its constructor is not public. Example::
             
             util = PyTango.Util.instance()
-            print util.get_host_name()"""
+            print(util.get_host_name())"""
 
     def __init__(self, args):
         args = copy.copy(args)
@@ -294,7 +294,7 @@ def __doc_Util():
 #
 #            Static method that gets the singleton object reference.
 #            If the class has not been initialised with it's init method,
-#            this method print a message and abort the device server process
+#            this method prints a message and aborts the device server process
 #
 #        Parameters :
 #            - exit : (bool)
@@ -558,7 +558,42 @@ def __doc_Util():
         Parameters : None
         Return     : (int) the maximun number of threads in the polling threads pool
     """ )
-    
+
+    document_method("is_svr_starting", """
+    is_svr_starting(self) -> bool
+
+            Check if the device server process is in its starting phase
+
+        Parameters : None
+        Return     : (bool) True if the server is in its starting phase
+
+        New in PyTango 8.0.0
+    """ )
+
+    document_method("is_svr_shutting_down", """
+    is_svr_shutting_down(self) -> bool
+
+            Check if the device server process is in its shutting down sequence
+
+        Parameters : None
+        Return     : (bool) True if the server is in its shutting down phase.
+
+        New in PyTango 8.0.0
+    """ )
+
+    document_method("is_device_restarting", """
+    is_device_restarting(self, (str)dev_name) -> bool
+
+            Check if the device is actually restarted by the device server
+            process admin device with its DevRestart command
+
+        Parameters :
+            dev_name : (str) device name
+        Return     : (bool) True if the device is restarting.
+
+        New in PyTango 8.0.0
+    """ )
+            
     document_method("get_sub_dev_diag", """
     get_sub_dev_diag(self) -> SubDevDiag
 
@@ -666,7 +701,7 @@ def __doc_Util():
 #        Return     : None
 #    """ )
 
-def init(doc=True):
+def pyutil_init(doc=True):
     __init_Util()
     if doc:
         __doc_Util()
diff --git a/PyTango/release.py b/PyTango/release.py
index 7b1a42d..0770dfd 100644
--- a/PyTango/release.py
+++ b/PyTango/release.py
@@ -33,27 +33,33 @@ class Release:
     """
         Release information:
             - name : (str) package name
-            - version_info : (tuple<int,int,int,str,int>) The five components of the version number: major, minor, micro, releaselevel, and serial.
+            - version_info : (tuple<int,int,int,str,int>) The five components
+              of the version number: major, minor, micro, releaselevel, and
+              serial.
             - version : (str) package version in format <major>.<minor>.<micro>
-            - version_long : (str) package version in format <major>.<minor>.<micro><releaselevel><serial>
-            - version_description : (str) short description for the current version
+            - version_long : (str) package version in format
+              <major>.<minor>.<micro><releaselevel><serial>
+            - version_description : (str) short description for the current
+              version
             - version_number : (int) <major>*100 + <minor>*10 + <micro>
             - description : (str) package description
             - long_description : (str) longer package description
-            - authors : (dict<str(last name), tuple<str(full name),str(email)>>) package authors
+            - authors : (dict<str(last name), tuple<str(full name),str(email)>>)
+              package authors
             - url : (str) package url
             - download_url : (str) package download url
             - platform : (seq<str>) list of available platforms
             - keywords : (seq<str>) list of keywords
             - license : (str) the license"""
     name = 'PyTango'
-    version_info = (7, 2, 3, 'final', 0)
+    version_info = (8, 0, 0, 'final', 0)
     version = '.'.join(map(str, version_info[:3]))
     version_long = version + ''.join(map(str, version_info[3:]))
-    version_description = 'This version implements the C++ Tango 7.2 API.'
+    version_description = 'This version implements the C++ Tango 8.0 API.'
     version_number = int(version.replace('.',''))
     description = 'A python binding for the Tango control system'
-    long_description = 'This module implements the Python Tango Device API mapping'
+    long_description = 'This module implements the Python Tango Device API ' \
+                       'mapping.'
     license = 'LGPL'
     authors = { 'Coutinho' : ('Tiago Coutinho' , 'tcoutinho at cells.es') }
     author_lines = "\n".join([ "%s <%s>" % x for x in authors.values()])
diff --git a/PyTango/tango_numpy.py b/PyTango/tango_numpy.py
index bb3edaf..98649bd 100644
--- a/PyTango/tango_numpy.py
+++ b/PyTango/tango_numpy.py
@@ -29,25 +29,27 @@ __all__ = [ "NumpyType", "numpy_type", "numpy_spectrum", "numpy_image" ]
 
 __docformat__ = "restructuredtext"
 
-import _PyTango
+from ._PyTango import Except
+from ._PyTango import constants
+
+from .attribute_proxy import AttributeProxy
+import collections
 
 def _numpy_invalid(*args, **kwds):
-    _PyTango.Except.throw_exception(
+    Except.throw_exception(
         "PyTango_InvalidConversion",
         "There's no registered conversor to numpy.",
         "NumpyType.tango_to_numpy"
     )
 
 def _define_numpy():
-    if not _PyTango.constants.NUMPY_SUPPORT:
+    if not constants.NUMPY_SUPPORT:
         return None, _numpy_invalid, _numpy_invalid, _numpy_invalid
     
     try:
         import numpy
         import operator
 
-        from attribute_proxy import AttributeProxy
-
         ArgType = _PyTango.CmdArgType
         AttributeInfo = _PyTango.AttributeInfo
         Attribute = _PyTango.Attribute
@@ -115,7 +117,7 @@ def _define_numpy():
                         - sequence:
                 """
                 np_type = NumpyType.tango_to_numpy(tg_type)
-                if operator.isSequenceType(dim_x):
+                if isinstance(dim_x, collections.Sequence):
                     return numpy.array(dim_x, dtype=np_type)
                 else:
                     return numpy.ndarray(shape=(dim_x,), dtype=np_type)
diff --git a/PyTango/time_val.py b/PyTango/time_val.py
index c3d7fae..c0edd3a 100644
--- a/PyTango/time_val.py
+++ b/PyTango/time_val.py
@@ -25,7 +25,7 @@
 This is an internal PyTango module.
 """
 
-__all__ = []
+__all__ = ["time_val_init"]
 
 __docformat__ = "restructuredtext"
 
@@ -33,7 +33,8 @@ import time
 import datetime
 import operator
 
-from _PyTango import TimeVal
+from ._PyTango import TimeVal
+import numbers
 
 def __TimeVal__init(self, a=None, b=None, c=None):
     TimeVal.__init_original(self)
@@ -44,7 +45,7 @@ def __TimeVal__init(self, a=None, b=None, c=None):
         assert(b is None and c is None)
         a = time.mktime(a.timetuple()) + a.microsecond*1E-6
 
-    elif operator.isNumberType(a):
+    elif isinstance(a, numbers.Number):
         if b is None:
             self.tv_sec = int(a)
             usec = (a - self.tv_sec) * 1E6
@@ -192,6 +193,6 @@ def __init_TimeVal():
     TimeVal.isoformat = __TimeVal__isoformat
     TimeVal.__str__ = __TimeVal__str__
     
-def init(doc=True):
+def time_val_init(doc=True):
     __init_TimeVal()
 
diff --git a/PyTango/utils.py b/PyTango/utils.py
index fe0248b..fbbb24f 100644
--- a/PyTango/utils.py
+++ b/PyTango/utils.py
@@ -26,8 +26,10 @@ This is an internal PyTango module.
 """
 
 from __future__ import with_statement
+from __future__ import print_function
 
-__all__ = [ "is_scalar_type", "is_array_type", "is_numerical_type", 
+__all__ = [ "is_pure_str", "is_seq", "is_non_str_seq", "is_integer",
+            "is_number", "is_scalar_type", "is_array_type", "is_numerical_type",
             "is_int_type", "is_float_type", "obj_2_str", "seqStr_2_obj",
             "document_method", "document_static_method", "document_enum",
             "CaselessList", "CaselessDict", "EventCallBack", "get_home",
@@ -37,13 +39,13 @@ __docformat__ = "restructuredtext"
 
 import sys
 import os
-import socket
-import types
-import operator
+import collections
+import numbers
 
-from _PyTango import StdStringVector, StdDoubleVector
-from _PyTango import DbData, DbDevInfos, DbDevExportInfos, CmdArgType, AttrDataFormat
-from _PyTango import EventData, AttrConfEventData, DataReadyEventData
+from ._PyTango import StdStringVector, StdDoubleVector, \
+    DbData, DbDevInfos, DbDevExportInfos, CmdArgType, AttrDataFormat, \
+    EventData, AttrConfEventData, DataReadyEventData, DevFailed
+from ._PyTango import constants
 
 _scalar_int_types = (CmdArgType.DevShort, CmdArgType.DevUShort,
     CmdArgType.DevInt, CmdArgType.DevLong, CmdArgType.DevULong,
@@ -88,6 +90,50 @@ _scalar_to_array_type = {
     CmdArgType.ConstDevString : CmdArgType.DevVarStringArray,
 }
 
+__str_klasses = str,
+__int_klasses = int,
+__number_klasses = numbers.Number,
+
+__use_unicode = False
+try:
+    unicode
+    __use_unicode = True
+    __str_klasses = tuple(list(__str_klasses) + [unicode])
+except:
+    pass
+
+__use_long = False
+try:
+    long
+    __use_long = True
+    __int_klasses = tuple(list(__int_klasses) + [long])
+except:
+    pass
+
+if constants.NUMPY_SUPPORT:
+    import numpy
+    __int_klasses = tuple(list(__int_klasses) + [numpy.integer])
+    __number_klasses = tuple(list(__number_klasses) + [numpy.number])
+
+__str_klasses = tuple(__str_klasses)
+__int_klasses = tuple(__int_klasses)
+__number_klasses = tuple(__number_klasses)
+
+def is_pure_str(obj):
+    return isinstance(obj , __str_klasses)
+
+def is_seq(obj):
+    return isinstance(obj, (collections.Sequence, bytearray))
+
+def is_non_str_seq(obj):
+    return is_seq(obj) and not is_pure_str(obj)
+
+def is_integer(obj):
+    return isinstance(obj, __int_klasses)
+
+def is_number(obj):
+    return isinstance(obj, __number_klasses)
+
 def is_scalar(tg_type):
     """Tells if the given tango type is a scalar
     
@@ -333,8 +379,8 @@ def seqStr_2_obj(seq, tg_type, tg_format=None):
 
 def _seqStr_2_obj_from_type(seq, tg_type):
     
-    if type(seq) in types.StringTypes:
-        seq = (seq,)
+    if is_pure_str(seq):
+        seq = seq,
     
     #    Scalar cases
     global _scalar_int_types
@@ -423,7 +469,7 @@ def obj_2_str(obj, tg_type):
     ret = ""
     if tg_type in _scalar_types:
         # scalar cases
-        if operator.isSequenceType(obj):
+        if isinstance(obj, collections.Sequence):
             if not len(obj):
                 return ret
             obj = obj[0]
@@ -433,25 +479,39 @@ def obj_2_str(obj, tg_type):
         ret = '\n'.join([ str(i) for i in obj ])
     return ret
 
+def __get_meth_func(klass, method_name):
+    meth = getattr(klass, method_name)
+    func = meth
+    if hasattr(meth, '__func__'):
+        func = meth.__func__
+    elif hasattr(meth, 'im_func'):
+        func = meth.im_func
+    return meth, func
+
 def copy_doc(klass, fnname):
-    """Copies documentation string of a method from the super class into the rewritten method of the given class"""
-    getattr(klass, fnname).im_func.__doc__ = getattr(klass.__base__, fnname).im_func.__doc__
+    """Copies documentation string of a method from the super class into the
+    rewritten method of the given class"""
+    base_meth, base_func = __get_meth_func(klass.__base__, fnname)
+    meth, func = __get_meth_func(klass, fnname)
+    func.__doc__ = base_func.__doc__
 
 def document_method(klass, method_name, d, add=True):
+    meth, func = __get_meth_func(klass, method_name)
     if add:
-        cpp_doc = getattr(klass, method_name).__doc__
+        cpp_doc = meth.__doc__
         if cpp_doc:
-            getattr(klass, method_name).im_func.__doc__ = "%s\n%s" % (d, cpp_doc)
+            func.__doc__ = "%s\n%s" % (d, cpp_doc)
             return
-    getattr(klass, method_name).im_func.__doc__ = d
+    func.__doc__ = d
 
 def document_static_method(klass, method_name, d, add=True):
+    meth, func = __get_meth_func(klass, method_name)
     if add:
-        cpp_doc = getattr(klass, method_name).__doc__
+        cpp_doc = meth.__doc__
         if cpp_doc:
-            getattr(klass, method_name).__doc__ = "%s\n%s" % (d, cpp_doc)
+            meth.__doc__ = "%s\n%s" % (d, cpp_doc)
             return
-    getattr(klass, method_name).__doc__ = d
+    meth.__doc__ = d
 
 def document_enum(klass, enum_name, desc, append=True):
     # derived = type(base)('derived', (base,), {'__doc__': 'desc'})
@@ -723,8 +783,8 @@ def notifd2db(notifd_ior_file=__DEFAULT_FACT_IOR_FILE, files=None, host=None, ou
 def _notifd2db_file_db(ior_string, files, out=sys.stdout):
     raise RuntimeError("Not implemented yet")
 
-    print >>out, "going to export notification service event factory to " \
-                 "device server property file(s) ..."
+    print("going to export notification service event factory to " \
+          "device server property file(s) ...", file=out)
     for f in files:
         with file(f, "w"):
             pass
@@ -732,8 +792,8 @@ def _notifd2db_file_db(ior_string, files, out=sys.stdout):
 
 def _notifd2db_real_db(ior_string, host=None, out=sys.stdout):
     import PyTango
-    print >>out, "going to export notification service event factory to " \
-                 "Tango database ..."
+    print("going to export notification service event factory to " \
+          "Tango database ...", file=out)
                  
     num_retries = 3
     while num_retries > 0:
@@ -741,15 +801,16 @@ def _notifd2db_real_db(ior_string, host=None, out=sys.stdout):
             db = PyTango.Database()
             db.set_timeout_millis(10000)
             num_retries = 0
-        except PyTango.DevFailed, df:
+        except PyTango.DevFailed as df:
             num_retries -= 1
             if num_retries == 0:
-                print >>out, "Can't create Tango database object"
-                print >>out, str(df)
+                print("Can't create Tango database object", file=out)
+                print(str(df), file=out)
                 return
-            print >>out, "Can't create Tango database object, retrying...."
+            print("Can't create Tango database object, retrying....", file=out)
     
     if host is None:
+        import socket
         host_name = socket.getfqdn()
     
     global __NOTIFD_FACTORY_PREFIX
@@ -761,10 +822,10 @@ def _notifd2db_real_db(ior_string, host=None, out=sys.stdout):
     while num_retries > 0:
         try:
             db.command_inout("DbExportEvent", args)
-            print >>out, "Successfully exported notification service event " \
-                         "factory for host", host_name, "to Tango database !"
+            print("Successfully exported notification service event " \
+                  "factory for host", host_name, "to Tango database !", file=out)
             break
-        except PyTango.CommunicationFailed, cf:
+        except PyTango.CommunicationFailed as cf:
             if len(cf.errors) >= 2:
                 if cf.errors[1].reason == "API_DeviceTimedOut":
                     if num_retries > 0:
@@ -777,8 +838,8 @@ def _notifd2db_real_db(ior_string, host=None, out=sys.stdout):
             num_retries = 0
     
     if num_retries == 0:
-        print >>out, "Failed to export notification service event factory " \
-                     "to TANGO database"
+        print("Failed to export notification service event factory " \
+              "to TANGO database", file=out)
 
 
 class EventCallBack(object):
@@ -824,9 +885,9 @@ class EventCallBack(object):
         """Internal usage only"""
         try:
             self._push_event(evt)
-        except Exception, e:
-            print >>self._fd, "Unexpected error in callback for %s: %s" \
-                % (str(evt), str(e))
+        except Exception as e:
+            print("Unexpected error in callback for %s: %s" \
+                  % (str(evt), str(e)), file=self._fd)
     
     def _push_event(self, evt):
         """Internal usage only"""
@@ -855,12 +916,12 @@ class EventCallBack(object):
             attr_name = "<UNKNOWN>"
         try:
             value = self._get_value(evt)
-        except Exception, e:
+        except Exception as e:
             value = "Unexpected exception in getting event value: %s" % str(e)
         d = { "date" : date, "reception_date" : reception_date,
               "type" : evt_type, "dev_name" : dev_name, "name" : attr_name,
               "value" : value }
-        print >>self._fd, self._msg.format(**d)
+        print(self._msg.format(**d), file=self._fd)
 
     def _append(self, evt):
         """Internal usage only"""
@@ -960,3 +1021,59 @@ def from_version_str_to_hex_str(version_str):
 def from_version_str_to_int(version_str):
     return int(from_version_str_to_hex_str(version_str, 16))
 
+def __server_run(classes, args=None, msg_stream=sys.stderr):
+    import PyTango
+    if msg_stream is None:
+        import io
+        msg_stream = io.BytesIO()
+    
+    if args is None:
+        args = sys.argv
+    util = PyTango.Util(args)
+
+    for klass_name, (klass_klass, klass) in classes.items():
+        util.add_class(klass_klass, klass, klass_name)
+    u_instance = PyTango.Util.instance()
+    u_instance.server_init()
+    msg_stream.write("Ready to accept request\n")
+    u_instance.server_run()
+    
+def server_run(classes, args=None, msg_stream=sys.stderr):
+    """Provides a simple way to run a tango server. It handles exceptions
+       by writting a message to the msg_stream
+       
+       For example, if you want to expose a server of type "MyServer" which
+       is defined by tango classes `MyServerClass` and `MyServer` then::
+       
+           import PyTango
+           PyTango.server_run({"MyServer": (MyServerClass, MyServer)})
+        
+       :param classes:
+           a dictionary where keyword is the tango class name and value is a 
+           sequence of Tango Class python class, and Tango python class
+       :type classes: dict
+       
+       :param args:
+           list of command line arguments [default: None, meaning use sys.argv]
+       :type args: list
+       
+       :param msg_stream:
+           stream where to put messages [default: sys.stderr]
+       
+       .. versionadded:: 8.0.0"""
+       
+    if msg_stream is None:
+        import io
+        msg_stream = io.BytesIO()
+    write = msg_stream.write
+    try:
+        return __server_run(classes, args=args)
+        write("Exiting:\n")
+    except KeyboardInterrupt:
+        write("Exiting: Keyboard interrupt\n")
+    except DevFailed as df:
+        write("Exiting: Server exited with PyTango.DevFailed:\n" + str(df) + "\n")
+    except Exception as e:
+        write("Exiting: Server exited with unforseen exception:\n" + str(e) + "\n")
+    write("\nExited\n")
+
diff --git a/PyTango3/tango3.py b/PyTango3/tango3.py
deleted file mode 100644
index 37db285..0000000
--- a/PyTango3/tango3.py
+++ /dev/null
@@ -1,156 +0,0 @@
-################################################################################
-##
-## This file is part of Taurus, a Tango User Interface Library
-## 
-## http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html
-##
-## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
-## 
-## PyTango is free software: you can redistribute it and/or modify
-## it under the terms of the GNU Lesser General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-## 
-## PyTango is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU Lesser General Public License for more details.
-## 
-## You should have received a copy of the GNU Lesser General Public License
-## along with PyTango.  If not, see <http://www.gnu.org/licenses/>.
-##
-################################################################################
-
-from PyTango import *
-
-import PyTango
-PyTango.EventType.CHANGE = PyTango.EventType.CHANGE_EVENT
-PyTango.EventType.QUALITY = PyTango.EventType.QUALITY_EVENT
-PyTango.EventType.PERIODIC = PyTango.EventType.PERIODIC_EVENT
-PyTango.EventType.ARCHIVE = PyTango.EventType.ARCHIVE_EVENT
-PyTango.EventType.USER = PyTango.EventType.USER_EVENT
-PyTango.EventType.DATA_READY = PyTango.EventType.DATA_READY_EVENT
-PyTango.EventType.ATTR_CONF = PyTango.EventType.ATTR_CONF_EVENT
-
-PyUtil = PyTango.Util
-PyDeviceClass = PyTango.DeviceClass
-
-set_attribute_value = PyTango.Attribute.set_value
-set_attribute_value_date_quality = PyTango.Attribute.set_value_date_quality
-
-class AttributeValue(PyTango.DeviceAttribute):
-    pass
-
-__original_DeviceProxy = PyTango.DeviceProxy
-
-class DeviceProxy3(__original_DeviceProxy):
-    defaultCommandExtractAs = ExtractAs.PyTango3
-
-    def __init__(self, *args, **kwds):
-        self.__init_state_status()
-        super(DeviceProxy3, self).__init__(*args, **kwds)
-
-    def __init_state_status(self):
-        if hasattr(self, "State"):
-            if callable(getattr(self, "State")):
-                self.dev_state = self.State
-        if hasattr(self, "Status"):
-            if callable(getattr(self, "Status")):
-                self.dev_status = self.Status
-
-    def write_attribute(self, attr_name, value=None):
-        if isinstance(attr_name, PyTango.DeviceAttribute):
-            if value is not None:
-                raise AttributeError('Using DeviceAttribute as attribute, only one parameter is expected.')
-            da = attr_name
-            attr_name = da.name
-            value = da.value
-        return super(DeviceProxy3, self).write_attribute(attr_name, value)
-
-    def read_attribute(self, attr_name, extract_as=DeviceAttribute.ExtractAs.PyTango3):
-        return super(DeviceProxy3, self).read_attribute(attr_name, extract_as)
-
-    def read_attribute_as_str(self, attr_name):
-        """
-            read_attribute_as_str( (DeviceProxy)self, (str)attr_name ) -> DeviceAttribute :
-                Read a single attribute.
-            Parameters :
-                    - attr_name  : A string, the name of the attribute to read.
-            Return     : a PyTango.DeviceAttribute. It's "value" field will contain
-                        a string representing the raw data sent by Tango.
-
-            Throws     : ConnectionFailed, CommunicationFailed, DevFailed from Device
-        """
-        return super(DeviceProxy3, self).read_attribute(attr_name, DeviceAttribute.ExtractAs.String)
-
-
-    def read_attributes(self, attr_names, extract_as=DeviceAttribute.ExtractAs.PyTango3):
-        return super(DeviceProxy3, self).read_attributes(attr_names, extract_as)
-
-    def read_attributes_as_str(self, attr_names):
-        """
-            read_attributes( (DeviceProxy)self, (object)attr_names, (ExtractAs)extract_as) -> object :
-                Read the list of specified attributes.
-            Parameters :
-                    - attr_names : A list of attributes to read. It should
-                                be a StdStringVector or a sequence of str.
-            Return     : a list of PyTango.DeviceAttribute. The "value" field
-                        is just a string representing the raw data.
-
-            Throws     : ConnectionFailed, CommunicationFailed, DevFailed from device
-        """
-        return super(DeviceProxy3, self).read_attribute(attr_names, DeviceAttribute.ExtractAs.String)
-
-
-
-    def write_read_attribute(self, attr_name, value, extract_as=DeviceAttribute.ExtractAs.PyTango3):
-        return super(DeviceProxy3, self).write_read_attribute(attr_name, extract_as)
-
-    def write_read_attribute_as_str(self, args):
-        """
-            write_read_attribute( (DeviceProxy)self, (str)attr_name, (object)values, (ExtractAs)xs) -> object :
-                Write then read a single attribute in a single network call. By
-                default (serialisation by device), the execution of this call in
-                the server can't be interrupted by other clients.
-            Parameters : see write_attribute(attr_name, value)
-            Return     : A PyTango.DeviceAttribute object. See read_attribute_as_str()
-
-            Throws     : ConnectionFailed, CommunicationFailed, DeviceUnlocked, DevFailed from device, WrongData
-            New in PyTango 7.0.0
-        """
-        return super(DeviceProxy3, self).write_read_attribute(attr_name, DeviceAttribute.ExtractAs.String)
-
-
-    def read_attributes_reply(self, idx, timeout=None, extract_as=DeviceAttribute.ExtractAs.PyTango3):
-        if timeout is None:
-            return super(DeviceProxy3, self).read_attributes_reply(idx, extract_as=extract_as)
-        else:
-            return super(DeviceProxy3, self).read_attributes_reply(idx, timeout, extract_as)
-
-    def read_attribute_reply(self, idx, timeout=None, extract_as=DeviceAttribute.ExtractAs.PyTango3):
-        return self.read_attributes_reply(idx, timeout, extract_as)[0]
-
-    def read_attributes_reply_as_str(self, idx, timeout=None):
-        """
-            See read_attributes_reply().
-            The result is given as in read_attributes_as_str().
-            New in PyTango 7.0.0
-        """
-        return self.read_attributes_reply(idx, timeout, extract_as=DeviceAttribute.ExtractAs.String)
-
-    def read_attribute_reply_as_str(self, idx, timeout=None):
-        """
-            New in PyTango 7.0.0
-        """
-        return self.read_attributes_reply_as_str(idx, timeout)[0]
-
-
-def __copy_doc(fnname):
-    getattr(DeviceProxy3, fnname).im_func.__doc__ = getattr(DeviceProxy3.__base__, fnname).im_func.__doc__
-
-__copy_doc('read_attribute')
-__copy_doc('read_attributes')
-__copy_doc('read_attribute_reply')
-__copy_doc('read_attributes_reply')
-
-DeviceProxy = DeviceProxy3
diff --git a/PyTango3/__init__.py b/cPyTango/__init__.py
similarity index 97%
rename from PyTango3/__init__.py
rename to cPyTango/__init__.py
index be52507..55acfd4 100644
--- a/PyTango3/__init__.py
+++ b/cPyTango/__init__.py
@@ -21,4 +21,4 @@
 ##
 ################################################################################
 
-from tango3 import *
+from cPyTango import *
diff --git a/cPyTango/cPyTango.py b/cPyTango/cPyTango.py
new file mode 100644
index 0000000..05e6fad
--- /dev/null
+++ b/cPyTango/cPyTango.py
@@ -0,0 +1,895 @@
+################################################################################
+##
+## This file is part of Taurus, a Tango User Interface Library
+## 
+## http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html
+##
+## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
+## 
+## PyTango is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+## 
+## PyTango is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU Lesser General Public License for more details.
+## 
+## You should have received a copy of the GNU Lesser General Public License
+## along with PyTango.  If not, see <http://www.gnu.org/licenses/>.
+##
+################################################################################
+
+import ctypes
+import ctypes.util
+import enumeration
+import time
+
+_tango_lib_name = ctypes.util.find_library("c_tango")
+
+if _tango_lib_name is None:
+    raise RuntimeError("Failed to find c_tango shared library")
+
+_ref      = ctypes.byref
+String    = ctypes.c_char_p
+StringPtr = ctypes.POINTER(String)
+Int       = ctypes.c_int
+IntPtr    = ctypes.POINTER(Int) 
+Enum      = ctypes.c_int
+Length    = ctypes.c_uint
+Bool      = ctypes.c_short
+
+c_tango = ctypes.CDLL(_tango_lib_name)
+
+TangoDataType = Enum
+TangoDataTypeEnum = enumeration.Enumeration("TangoDataTypeEnum", (
+    "DEV_VOID",
+    "DEV_BOOLEAN",
+    "DEV_SHORT",
+    "DEV_LONG",
+    "DEV_FLOAT",
+    "DEV_DOUBLE",
+    "DEV_USHORT",
+    "DEV_ULONG",
+    "DEV_STRING",
+    "DEVVAR_CHARARRAY",
+    "DEVVAR_SHORTARRAY",
+    "DEVVAR_LONGARRAY",
+    "DEVVAR_FLOATARRAY",
+    "DEVVAR_DOUBLEARRAY",
+    "DEVVAR_USHORTARRAY",
+    "DEVVAR_ULONGARRAY",
+    "DEVVAR_STRINGARRAY",
+    "DEVVAR_LONGSTRINGARRAY",
+    "DEVVAR_DOUBLESTRINGARRAY",
+    "DEV_STATE",
+    "CONST_DEV_STRING",
+    "DEVVAR_BOOLEANARRAY",
+    "DEV_UCHAR",
+    "DEV_LONG64",
+    "DEV_ULONG64",
+    "DEVVAR_LONG64ARRAY",
+    "DEVVAR_ULONG64ARRAY",
+    "DEV_INT" ) )
+locals().update(TangoDataTypeEnum.lookup)
+TangoDataTypePtr = ctypes.POINTER(TangoDataType)
+
+def _is_scalar(data_type):
+    if data_type <= TangoDataTypeEnum.DEV_STRING: return True
+    if data_type > TangoDataTypeEnum.DEV_STRING and data_type < TangoDataTypeEnum.DEV_STATE: return False
+    if data_type == TangoDataTypeEnum.DEVVAR_BOOLEANARRAY or \
+       data_type == TangoDataTypeEnum.DEVVAR_LONG64ARRAY or \
+       data_type == TangoDataTypeEnum.DEVVAR_ULONG64ARRAY:
+       return False
+    return True
+
+TangoDataTypeEnum.is_scalar = _is_scalar
+
+TangoDevState = Enum
+TangoDevStateEnum = enumeration.Enumeration("TangoDevStateEnum", (
+    "ON",
+    "OFF",
+    "CLOSE",
+    "OPEN",
+    "INSERT",
+    "EXTRACT",
+    "MOVING",
+    "STANDBY",
+    "FAULT",
+    "INIT",
+    "RUNNING",
+    "ALARM",
+    "DISABLE",
+    "UNKNOWN") )
+locals().update(TangoDevStateEnum.lookup)
+TangoDevStatePtr = ctypes.POINTER(TangoDevState)
+
+AttrQuality = Enum
+AttrQualityEnum = enumeration.Enumeration("AttrQualityEnum", (
+    "ATTR_VALID",
+    "ATTR_INVALID",
+    "ATTR_ALARM",
+    "ATTR_CHANGING", 
+    "ATTR_WARNING" ) )
+locals().update(AttrQualityEnum.lookup)
+AttrQualityPtr = ctypes.POINTER(AttrQuality)
+
+AttrWriteType = Enum
+AttrWriteTypeEnum = enumeration.Enumeration("AttrWriteTypeEnum", (
+   "READ",
+   "READ_WITH_WRITE",
+   "WRITE",
+   "READ_WRITE" ) )
+locals().update(AttrWriteTypeEnum.lookup)
+AttrWriteTypePtr = ctypes.POINTER(AttrWriteType)
+
+AttrDataFormat = Enum
+AttrDataFormatEnum = enumeration.Enumeration("AttrDataFormatEnum", (
+    "SCALAR",
+    "SPECTRUM",
+    "IMAGE" ) )
+locals().update(AttrDataFormatEnum.lookup)
+AttrDataFormatPtr = ctypes.POINTER(AttrDataFormat)
+
+DispLevel = Enum
+DispLevelEnum = enumeration.Enumeration("DispLevelEnum", (
+    "OPERATOR",
+    "EXPERT" ) )
+locals().update(DispLevelEnum.lookup)
+DispLevelPtr = ctypes.POINTER(DispLevel)
+
+ErrSeverity = Enum
+ErrSeverityEnum = enumeration.Enumeration("ErrSeverityEnum", (
+   "WARN",
+   "ERR",
+   "PANIC" ) )
+locals().update(ErrSeverityEnum.lookup)   
+ErrSeverityPtr = ctypes.POINTER(ErrSeverity)
+
+DevSource = Enum
+DevSourceEnum = enumeration.Enumeration("DevSourceEnum", (
+    "DEV",
+    "CACHE",
+    "CACHE_DEV" ) )
+locals().update(DevSourceEnum.lookup)  
+DevSourcePtr = ctypes.POINTER(DevSource)
+    
+TangoDevLong = ctypes.c_int32
+TangoDevLongPtr = ctypes.POINTER(TangoDevLong)
+TangoDevULong = ctypes.c_uint32
+TangoDevULongPtr = ctypes.POINTER(TangoDevULong)
+TangoDevLong64 = ctypes.c_int64
+TangoDevLong64Ptr = ctypes.POINTER(TangoDevLong64)
+TangoDevULong64 = ctypes.c_uint64
+TangoDevULong64Ptr = ctypes.POINTER(TangoDevULong64)
+
+
+class VarArray(ctypes.Structure):
+    
+    def __len__(self):
+        return self.length
+    
+    def __getitem__(self, i):
+        if not isinstance(i,int): raise TypeError("tuple indices must be integers")
+        if i < 0 or i > self.length-1: raise IndexError("tuple index out of range")
+        return self.sequence[i]
+
+
+class VarBoolArray(VarArray):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", ctypes.POINTER(ctypes.c_int16)) 
+        
+
+class VarCharArray(VarArray):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", ctypes.POINTER(ctypes.c_char)) 
+
+
+class VarShortArray(VarArray):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", ctypes.POINTER(ctypes.c_int16)) 
+
+
+class VarUShortArray(VarArray):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", ctypes.POINTER(ctypes.c_uint16)) 
+
+
+class VarLongArray(VarArray):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", TangoDevLongPtr) 
+
+
+class VarULongArray(VarArray):
+    _fields_ =  \
+        ("length", Length), \
+        ("sequence", TangoDevULongPtr) 
+
+
+class VarLong64Array(VarArray):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", TangoDevLong64Ptr) 
+
+
+class VarULong64Array(VarArray):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", TangoDevULong64Ptr) 
+
+
+class VarFloatArray(VarArray):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", ctypes.POINTER(ctypes.c_float)) 
+
+
+class VarDoubleArray(VarArray):
+    _fields_ =  \
+        ("length", Length), \
+        ("sequence", ctypes.POINTER(ctypes.c_double)) 
+    
+
+class VarStringArray(VarArray):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", StringPtr)
+    
+    def __str__(self):
+        l = self.length
+        if l == 1:
+            return self.sequence[0]
+        return str(list(self.sequence[:10]))
+VarStringArrayPtr = ctypes.POINTER(VarStringArray)
+
+class VarStateArray(VarArray):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", TangoDevStatePtr) 
+    
+    def __str__(self):
+        l = self.length
+        if l == 1:
+            return TangoDevStateEnum.whatis(self.sequence[0])
+        return map(TangoDevStateEnum.whatis, self.sequence[:10])
+        
+
+class TangoAttributeData(ctypes.Union):
+    _fields_ =  \
+        ("bool_arr", VarBoolArray), \
+        ("char_arr", VarCharArray), \
+        ("short_arr", VarShortArray), \
+        ("ushort_arr", VarUShortArray), \
+        ("long_arr", VarLongArray), \
+        ("ulong_arr", VarULongArray), \
+        ("long64_arr", VarLong64Array), \
+        ("ulong64_arr", VarULong64Array), \
+        ("float_arr", VarFloatArray), \
+        ("double_arr", VarDoubleArray), \
+        ("string_arr", VarStringArray), \
+        ("state_arr", VarStateArray)
+    
+    def get_raw(self, type):
+        if type == DEV_BOOLEAN:   return self.bool_arr
+        elif type == DEV_UCHAR:    return self.char_arr
+        elif type == DEV_SHORT:   return self.short_arr
+        elif type == DEV_USHORT:  return self.ushort_arr
+        elif type == DEV_LONG:    return self.long_arr
+        elif type == DEV_ULONG:   return self.ulong_arr
+        elif type == DEV_LONG64:  return self.long64_arr
+        elif type == DEV_ULONG64: return self.ulong64_arr
+        elif type == DEV_FLOAT:   return self.float_arr
+        elif type == DEV_DOUBLE:  return self.double_arr
+        elif type == DEV_STRING:  return self.string_arr
+        elif type == DEV_STATE:   return self.state_arr
+
+    def get(self, type):
+        raw = self.get_raw(type)
+        if TangoDataTypeEnum.is_scalar(type):
+            return raw[0]
+        return raw
+
+    def representation(self, type):
+        return str(self.get_raw(type))
+TangoAttributeDataPtr = ctypes.POINTER(TangoAttributeData)
+
+
+class TangoCommandData(ctypes.Union):
+    _fields_ = \
+        ("bool_val", Bool), \
+        ("short_val", ctypes.c_short), \
+        ("ushort_val", ctypes.c_ushort), \
+        ("long_val", ctypes.c_int32), \
+        ("ulong_val", ctypes.c_uint32), \
+        ("float_val", ctypes.c_float), \
+        ("double_val", ctypes.c_double), \
+        ("string_val", ctypes.c_char_p), \
+        ("state_val", TangoDevState), \
+        ("long64_val", ctypes.c_int64), \
+        ("ulong64_val", ctypes.c_uint64), \
+        ("bool_arr", VarBoolArray), \
+        ("char_arr", VarCharArray), \
+        ("short_arr", VarShortArray), \
+        ("ushort_arr", VarUShortArray), \
+        ("long_arr", VarLongArray), \
+        ("ulong_arr", VarULongArray), \
+        ("long64_arr", VarLong64Array), \
+        ("ulong64_arr", VarULong64Array), \
+        ("float_arr", VarFloatArray), \
+        ("double_arr", VarDoubleArray), \
+        ("string_arr", VarStringArray), \
+        ("state_arr", VarStateArray),
+TangoCommandDataPtr = ctypes.POINTER(TangoCommandData)
+
+
+class TangoPropertyData(ctypes.Union):
+    _fields_ = \
+        ("bool_val", Bool), \
+        ("char_val", ctypes.c_char), \
+        ("short_val", ctypes.c_short), \
+        ("ushort_val", ctypes.c_ushort), \
+        ("long_val", ctypes.c_int32), \
+        ("ulong_val", ctypes.c_uint32), \
+        ("float_val", ctypes.c_float), \
+        ("double_val", ctypes.c_double), \
+        ("string_val", ctypes.c_char_p), \
+        ("long64_val", ctypes.c_int64), \
+        ("ulong64_val", ctypes.c_uint64), \
+        ("short_arr", VarShortArray), \
+        ("ushort_arr", VarUShortArray), \
+        ("long_arr", VarLongArray), \
+        ("ulong_arr", VarULongArray), \
+        ("long64_arr", VarLong64Array), \
+        ("ulong64_arr", VarULong64Array), \
+        ("float_arr", VarFloatArray), \
+        ("double_arr", VarDoubleArray), \
+        ("string_arr", VarStringArray),
+TangoPropertyDataPtr = ctypes.POINTER(TangoPropertyData)
+
+
+class CommandData(ctypes.Structure):
+    _fields_ = \
+        ("arg_type",TangoDataType), \
+        ("cmd_data",TangoCommandData)
+CommandDataPtr = ctypes.POINTER(CommandData)
+
+
+_time_t = ctypes.c_long
+_suseconds_t = ctypes.c_long
+
+class timeval(ctypes.Structure):
+    _fields_ = \
+        ("tv_sec", _time_t), \
+        ("tv_usec", _suseconds_t),
+    
+    def __str__(self):
+        return time.ctime(self.tv_sec + 1E-6 * self.tv_usec)
+timevalPtr = ctypes.POINTER(timeval)
+
+
+class AttributeData(ctypes.Structure):
+    _fields_ = \
+        ("data_type", TangoDataType), \
+        ("attr_data", TangoAttributeData), \
+        ("quality", AttrQuality), \
+        ("name", String), \
+        ("dim_x", Int), \
+        ("dim_y", Int), \
+        ("time_stamp", timeval)
+    
+    def __str__(self):
+        s = "AttributeData[\n"
+        s += "name: %s\n" % self.name
+        s += "data_type: %s\n" % TangoDataTypeEnum.whatis(self.data_type)
+        s += "quality: %s\n" % AttrQualityEnum.whatis(self.quality)
+        s += "dim_x: %d\n" % self.dim_x
+        s += "dim_y: %d\n" % self.dim_y
+        s += "time_stamp: %s\n" % self.time_stamp
+        s += "attr_data: %s\n" % str(self.attr_data.representation(self.data_type))
+        s += "]\n"
+        return s
+    
+    def get_raw_data(self):
+        return self.attr_data.get_raw(self.data_type)
+
+    def get_data(self):
+        return self.attr_data.get(self.data_type)
+AttributeDataPtr = ctypes.POINTER(AttributeData)
+
+
+class AttributeDataList(ctypes.Structure):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", AttributeDataPtr)
+
+    def __len__(self):
+        return self.length
+    
+    def __getitem__(self, i):
+        if not isinstance(i,int): raise TypeError("tuple indices must be integers")
+        if i < 0 or i > self.length-1: raise IndexError("tuple index out of range")
+        return self.sequence[i]
+    
+    def __str__(self):
+        s = "AttributeDataList[\n"
+        for attr in self: s += attr
+        return s
+AttributeDataListPtr = ctypes.POINTER(AttributeDataList)
+
+                        
+class DevFailed(ctypes.Structure):
+    _fields_ = \
+        ("desc", String), \
+        ("reason", String), \
+        ("origin", String), \
+        ("severity", ErrSeverity)
+    
+    def __str__(self):
+        s  = "Severity    : %d\n" % self.severity
+        s += "Reason      : %s\n" % self.reason
+        s += "Description : %s\n" % self.desc
+        s += "Origin      : %s\n\n" % self.origin
+        return s    
+
+    def __repr__(self):
+        return self.__str__()
+DevFailedPtr = ctypes.POINTER(DevFailed)
+
+
+class ErrorStack(ctypes.Structure):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", DevFailedPtr) 
+
+    def __len__(self):
+        return self.length
+    
+    def __getitem__(self, i):
+        if not isinstance(i,int): raise TypeError("tuple indices must be integers")
+        if i < 0 or i > self.length-1: raise IndexError("tuple index out of range")
+        return self.sequence[i]
+    
+    def __str__(self):
+        s = "\nTango exception:\n"
+        for i in xrange(self.length):
+            s += str(self.sequence[i])
+        return s
+        
+    def __repr__(self):
+        return self.__str__()
+ErrorStackPtr = ctypes.POINTER(ErrorStack)
+
+
+class CommandInfo(ctypes.Structure):
+    _fields_ = \
+        ("cmd_name", String), \
+        ("cmd_tag", Int), \
+        ("in_type", Int), \
+        ("out_type", Int), \
+        ("in_type_desc", String), \
+        ("out_type_desc", String), \
+        ("disp_level", DispLevel) 
+CommandInfoPtr = ctypes.POINTER(CommandInfo)
+
+
+class CommandInfoList(ctypes.Structure):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", CommandInfoPtr)
+CommandInfoListPtr = ctypes.POINTER(CommandInfoList)
+
+
+class AttributeInfo(ctypes.Structure):
+    _fields_ = \
+        ("name", String), \
+        ("writable", AttrWriteType), \
+        ("data_format", AttrDataFormat), \
+        ("data_type", TangoDataType), \
+        ("max_dim_x", Int), \
+        ("max_dim_y", Int), \
+        ("description", String), \
+        ("label", String), \
+        ("unit", String), \
+        ("standard_unit", String), \
+        ("display_unit", String), \
+        ("format", String), \
+        ("min_value", String), \
+        ("max_value", String), \
+        ("min_alarm", String), \
+        ("max_alarm", String), \
+        ("writable_attr_name", String), \
+        ("disp_level", DispLevel)
+AttributeInfoPtr = ctypes.POINTER(AttributeInfo)
+
+
+class AttributeInfoList(ctypes.Structure):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", AttributeInfoPtr)
+AttributeInfoListPtr = ctypes.POINTER(AttributeInfoList)
+
+
+class DbDatum(ctypes.Structure):
+    _fields_ = \
+        ("property_name", String), \
+        ("data_type", TangoDataType), \
+        ("prop_data", TangoPropertyData), \
+        ("is_empty", Bool), \
+        ("wrong_data_type", Bool)
+DbDatumPtr = ctypes.POINTER(DbDatum)
+
+
+class DbData(ctypes.Structure):
+    _fields_ = \
+        ("length", Length), \
+        ("sequence", DbDatumPtr)
+DbDataPtr = ctypes.POINTER(DbData)
+
+
+DeviceProxyPtr    = ctypes.c_void_p
+DeviceProxyPtrPtr = ctypes.POINTER(DeviceProxyPtr)
+DatabasePtr       = ctypes.c_void_p
+DatabasePtrPtr    = ctypes.POINTER(DatabasePtr)
+
+
+c_tango.tango_create_device_proxy.argtypes = (String, DeviceProxyPtrPtr, ErrorStackPtr, )
+c_tango.tango_delete_device_proxy.argtypes = (DeviceProxyPtrPtr, ErrorStackPtr, )
+c_tango.tango_set_timeout_millis.argtypes = (DeviceProxyPtr, Int, ErrorStackPtr, )
+c_tango.tango_get_timeout_millis.argtypes = (DeviceProxyPtr, IntPtr, ErrorStackPtr, )
+c_tango.tango_set_source.argtypes = (DeviceProxyPtr, DevSource, ErrorStackPtr, )
+c_tango.tango_get_source.argtypes = (DeviceProxyPtr, DevSourcePtr, ErrorStackPtr, )
+c_tango.tango_command_query.argtypes = (DeviceProxyPtr, String, CommandInfoPtr, ErrorStackPtr, )
+c_tango.tango_command_list_query.argtypes = (DeviceProxyPtr, CommandInfoListPtr, ErrorStackPtr, )
+c_tango.tango_command_inout.argtypes = (DeviceProxyPtr, String, CommandDataPtr, CommandDataPtr, ErrorStackPtr, )
+c_tango.tango_free_CommandData.argtypes = (CommandDataPtr, )
+c_tango.tango_free_CommandInfo.argtypes = (CommandInfoPtr, )
+c_tango.tango_free_CommandInfoList.argtypes = (CommandInfoListPtr, )
+c_tango.tango_get_attribute_list.argtypes = (DeviceProxyPtr, VarStringArrayPtr, ErrorStackPtr, )
+c_tango.tango_get_attribute_config.argtypes = (DeviceProxyPtr, VarStringArrayPtr, AttributeInfoListPtr, ErrorStackPtr, )
+c_tango.tango_attribute_list_query.argtypes = (DeviceProxyPtr, AttributeInfoListPtr, ErrorStackPtr, )
+c_tango.tango_read_attribute.argtypes = (DeviceProxyPtr, String, AttributeDataPtr, ErrorStackPtr, )
+c_tango.tango_write_attribute.argtypes = (DeviceProxyPtr, String, AttributeDataPtr, ErrorStackPtr, )
+c_tango.tango_read_attributes.argtypes = (DeviceProxyPtr, VarStringArrayPtr, AttributeDataListPtr, ErrorStackPtr, )
+c_tango.tango_write_attributes.argtypes = (DeviceProxyPtr, AttributeDataListPtr, ErrorStackPtr, )
+c_tango.tango_free_AttributeData.argtypes = (AttributeDataPtr, )
+c_tango.tango_free_AttributeDataList.argtypes = (AttributeDataListPtr, )
+c_tango.tango_free_VarStringArray.argtypes = (VarStringArrayPtr, )
+c_tango.tango_print_ErrorStack.argtypes = (ErrorStackPtr, )
+c_tango.tango_free_ErrorStack.argtypes = (ErrorStackPtr, )
+c_tango.tango_create_database_proxy.argtypes = (DatabasePtrPtr, ErrorStackPtr, )
+c_tango.tango_delete_database_proxy.argtypes = (DatabasePtrPtr, ErrorStackPtr, )
+c_tango.tango_get_device_exported.argtypes = (DatabasePtr, String, DbDatumPtr, ErrorStackPtr, )
+c_tango.tango_get_device_exported_for_class.argtypes = (DatabasePtr, String, DbDatumPtr, ErrorStackPtr, )
+c_tango.tango_get_object_list.argtypes = (DatabasePtr, String, DbDatumPtr, ErrorStackPtr, )
+c_tango.tango_get_object_property_list.argtypes = (DatabasePtr, String, String, DbDatumPtr, ErrorStackPtr, )
+c_tango.tango_get_property.argtypes = (DatabasePtr, String, DbDataPtr, ErrorStackPtr, )
+c_tango.tango_put_property.argtypes = (DatabasePtr, String, DbDataPtr, ErrorStackPtr, )
+c_tango.tango_delete_property.argtypes = (DatabasePtr, String, DbDataPtr, ErrorStackPtr, )
+c_tango.tango_get_device_property.argtypes = (DeviceProxyPtr, DbDataPtr, ErrorStackPtr, )
+c_tango.tango_put_device_property.argtypes = (DeviceProxyPtr, DbDataPtr, ErrorStackPtr, )
+c_tango.tango_delete_device_property.argtypes = (DeviceProxyPtr, DbDataPtr, ErrorStackPtr, )
+c_tango.tango_free_DbDatum.argtypes = (DbDatumPtr, )
+c_tango.tango_free_DbData.argtypes = (DbDataPtr, )
+
+
+def tango_create_device_proxy(dev_name):
+    dev_name = ctypes.create_string_buffer(dev_name)
+    dev_ptr = ctypes.c_void_p()
+    err_stack = ErrorStack()
+    result = c_tango.tango_create_device_proxy(dev_name, _ref(dev_ptr), _ref(err_stack))
+    if result:
+        return dev_ptr
+    raise Exception(err_stack)
+
+def tango_delete_device_proxy(dev_ptr):
+    err_stack = ErrorStack()
+    result = c_tango.tango_delete_device_proxy(_ref(dev_ptr), _ref(err_stack))
+    if result:
+        return True
+    raise Exception(err_stack)
+
+def tango_set_timeout_millis(dev_ptr, millis):
+    err_stack = ErrorStack()
+    millis = ctypes.c_int(millis)
+    result = c_tango.tango_set_timeout_millis(dev_ptr, millis, _ref(err_stack))
+    if result:
+        return True
+    raise Exception(err_stack)    
+
+def tango_get_timeout_millis(dev_ptr):
+    err_stack = ErrorStack()
+    millis = ctypes.c_int()
+    result = c_tango.tango_get_timeout_millis(dev_ptr, _ref(millis), _ref(err_stack))
+    if result:
+        return millis
+    raise Exception(err_stack)      
+
+def tango_set_source(dev_ptr, src):
+    """src -> DevSource"""
+    err_stack = ErrorStack()
+    result = c_tango.tango_set_source(dev_ptr, src, _ref(err_stack))
+    if result:
+        return True
+    raise Exception(err_stack)   
+    
+def tango_get_source(dev_ptr):
+    err_stack = ErrorStack()
+    src = ctypes.c_int()
+    result = c_tango.tango_get_source(dev_ptr, _ref(src), _ref(err_stack))
+    if result:
+        return src
+    raise Exception(err_stack)
+    
+def tango_command_query(dev_ptr, cmd_name):
+    err_stack = ErrorStack()
+    cmd_name = ctypes.create_string_buffer(cmd_name)
+    cmd_info = CommandInfo()
+    result = c_tango.tango_command_query(dev_ptr, cmd_name, _ref(cmd_info), _ref(err_stack))
+    if result:
+        return cmd_info
+    raise Exception(err_stack)    
+
+def tango_command_list_query(dev_ptr):
+    err_stack = ErrorStack()
+    cmd_info_list = CommandInfoList()
+    result = c_tango.tango_command_list_query(dev_ptr, _ref(cmd_info_list), _ref(err_stack))
+    if result:
+        return cmd_info_list
+    raise Exception(err_stack)    
+
+def tango_command_inout(dev_ptr, cmd_name, arg_in):
+    """arg_in->CommandData"""
+    err_stack = ErrorStack()
+    cmd_name = ctypes.create_string_buffer(cmd_name)
+    arg_out = CommandData()
+    result = c_tango.tango_command_inout(dev_ptr, cmd_name, _ref(arg_in), _ref(arg_out), _ref(err_stack))
+    if result:
+        return arg_out
+    raise Exception(err_stack)  
+    
+def tango_free_CommandData(cmd_data):
+    c_tango.tango_free_CommandData(_ref(cmd_data))
+
+def tango_free_CommandInfo(cmd_info):
+    c_tango.tango_free_CommandInfo(_ref(cmd_info))
+    
+def tango_free_CommandInfoList(cmd_info_list):
+    c_tango.tango_free_CommandInfoList(_ref(cmd_info_list))
+
+def tango_get_attribute_list(dev_ptr):
+    err_stack = ErrorStack()
+    attr_names = VarStringArray()
+    result = c_tango.tango_get_attribute_list(dev_ptr, _ref(attr_names), _ref(err_stack))
+    if result:
+        return attr_names
+    raise Exception(err_stack)  
+    
+def tango_get_attribute_config(dev_ptr, attr_names):
+    print "TODO"
+    return
+    err_stack = ErrorStack()
+    attr_names = VarStringArray()
+    attr_info_list = AttributeInfoList()
+    result = c_tango.tango_get_attribute_config(dev_ptr, _ref(attr_names), _ref(attr_info_list), _ref(err_stack))
+    if result:
+        return attr_info_list
+    raise Exception(err_stack)  
+    
+def tango_attribute_list_query(dev_ptr):
+    err_stack = ErrorStack()
+    attr_info_list = AttributeInfoList()
+    result = c_tango.tango_attribute_list_query(dev_ptr, _ref(attr_info_list), _ref(err_stack))
+    if result:
+        return attr_info_list
+    raise Exception(err_stack) 
+    
+def tango_read_attribute(dev_ptr, attr_name):
+    attr_name = ctypes.create_string_buffer(attr_name)
+    attr_data = AttributeData()
+    err_stack = ErrorStack()
+    result = c_tango.tango_read_attribute(dev_ptr, attr_name, _ref(attr_data), _ref(err_stack))    
+    if result:
+        return attr_data
+    raise Exception(err_stack)
+
+def tango_write_attribute(dev_ptr, attr_name, value):
+    print "TODO"
+    return
+    attr_data = AttributeData()
+    attr_data.name = ctypes.create_string_buffer(attr_name)
+    attr_data.attr_data = value
+    err_stack = ErrorStack()
+    result = c_tango.tango_write_attribute(dev_ptr, attr_name, _ref(attr_data), _ref(err_stack))    
+    if result:
+        return True
+    raise Exception(err_stack)
+
+def tango_read_attributes(dev_ptr, attr_names):
+    print "TODO"
+    return
+    attr_data_list = AttributeDataList()
+    attr_names = VarStringArray()
+    err_stack = ErrorStack()
+    result = c_tango.tango_read_attribute(dev_ptr, _ref(attr_names), _ref(attr_data_list), _ref(err_stack))    
+    if result:
+        return attr_data
+    raise Exception(err_stack)
+    
+def tango_write_attributes(dev_ptr, attr_data_list):
+    """attr_data_list->AttributeDataList"""
+    err_stack = ErrorStack()
+    result = c_tango.tango_write_attributes(dev_ptr, _ref(attr_data_list), _ref(err_stack))    
+    if result:
+        return True
+    raise Exception(err_stack)
+    
+def tango_free_AttributeData(attr_data):
+    c_tango.tango_free_AttributeData(_ref(attr_data))
+    
+def tango_free_AttributeDataList(attr_data_list):
+    c_tango.tango_free_AttributeDataList(_ref(attr_data_list))
+    
+def tango_free_VarStringArray(str_array):
+    c_tango.tango_free_VarStringArray(_ref(str_array))
+
+def tango_print_ErrorStack(err_stack):
+    """Should not be used. This function prints to STDOUT instead of sys.stdout.
+       Use: 'print err_stack' instead"""
+    c_tango.tango_print_ErrorStack(_ref(err_stack))
+
+def tango_free_ErrorStack(err_stack):
+    c_tango.tango_free_ErrorStack(_ref(err_stack))
+
+def tango_create_database_proxy():
+    err_stack = ErrorStack()
+    db_ptr = ctypes.c_void_p()
+    result = c_tango.tango_create_database_proxy(_ref(db_ptr), _ref(err_stack))    
+    if result:
+        return db_ptr
+    raise Exception(err_stack)
+
+def tango_delete_database_proxy(db_ptr):
+    err_stack = ErrorStack()
+    result = c_tango.tango_delete_database_proxy(_ref(db_ptr), _ref(err_stack))    
+    if result:
+        return True
+    raise Exception(err_stack)
+
+def tango_get_device_exported(db_ptr, name_filter):
+    err_stack = ErrorStack()
+    name_filter = ctypes.create_string_buffer(name_filter)
+    db_datum = DbDatum()
+    result = c_tango.tango_get_device_exported(db_ptr, name_filter, _ref(db_datum), _ref(err_stack))    
+    if result:
+        return db_datum
+    raise Exception(err_stack)
+
+def tango_get_device_exported_for_class(db_ptr, class_name):
+    err_stack = ErrorStack()
+    class_name = ctypes.create_string_buffer(class_name)
+    db_datum = DbDatum()
+    result = c_tango.tango_get_device_exported_for_class(db_ptr, class_name, _ref(db_datum), _ref(err_stack))    
+    if result:
+        return db_datum
+    raise Exception(err_stack)
+
+def tango_get_object_list(db_ptr, name_filter):
+    err_stack = ErrorStack()
+    name_filter = ctypes.create_string_buffer(name_filter)
+    db_datum = DbDatum()
+    result = c_tango.tango_get_object_list(db_ptr, name_filter, _ref(db_datum), _ref(err_stack))    
+    if result:
+        return db_datum
+    raise Exception(err_stack)
+
+def tango_get_object_property_list(db_ptr, obj_name, name_filter):
+    err_stack = ErrorStack()
+    obj_name = ctypes.create_string_buffer(obj_name)
+    name_filter = ctypes.create_string_buffer(name_filter)
+    db_datum = DbDatum()
+    result = c_tango.tango_get_object_property_list(db_ptr, obj_name, name_filter, _ref(db_datum), _ref(err_stack))    
+    if result:
+        return db_datum
+    raise Exception(err_stack)
+
+def tango_get_property(db_ptr, obj_name):
+    err_stack = ErrorStack()
+    obj_name = ctypes.create_string_buffer(obj_name)
+    db_data = DbData()
+    result = c_tango.tango_get_property(db_ptr, obj_name, _ref(db_data), _ref(err_stack))    
+    if result:
+        return db_datum
+    raise Exception(err_stack)
+
+def tango_put_property(db_ptr, obj_name, prop_list):
+    """prop_list -> DbData"""
+    err_stack = ErrorStack()
+    obj_name = ctypes.create_string_buffer(obj_name)
+    result = c_tango.tango_put_property(db_ptr, obj_name, _ref(prop_list), _ref(err_stack))    
+    if result:
+        return True
+    raise Exception(err_stack)
+
+def tango_delete_property(db_ptr, obj_name, prop_list):
+    """prop_list -> DbData"""
+    err_stack = ErrorStack()
+    obj_name = ctypes.create_string_buffer(obj_name)
+    result = c_tango.tango_delete_property(db_ptr, obj_name, _ref(prop_list), _ref(err_stack))    
+    if result:
+        return True
+    raise Exception(err_stack)
+    
+def tango_get_device_property(dev_ptr, prop_list):
+    """prop_list -> DbData"""
+    err_stack = ErrorStack()
+    result = c_tango.tango_get_device_property(dev_ptr, _ref(prop_list), _ref(err_stack))    
+    if result:
+        return prop_list
+    raise Exception(err_stack)
+
+def tango_put_device_property(dev_ptr, prop_list):
+    """prop_list -> DbData"""
+    err_stack = ErrorStack()
+    result = c_tango.tango_put_device_property(dev_ptr, _ref(prop_list), _ref(err_stack))    
+    if result:
+        return True
+    raise Exception(err_stack)
+
+def tango_delete_device_property(dev_ptr, prop_list):
+    """prop_list -> DbData"""
+    err_stack = ErrorStack()
+    result = c_tango.tango_delete_device_property(dev_ptr, _ref(prop_list), _ref(err_stack))    
+    if result:
+        return True
+    raise Exception(err_stack)
+
+def tango_free_DbDatum(db_datum):
+    c_tango.tango_free_DbDatum(_ref(db_datum))
+    
+def tango_free_DbData(db_data):
+    c_tango.tango_free_DbData(_ref(db_data))
+
+
+class DeviceProxy:
+    def __init__(self, dev_name):
+        self._dev_name = dev_name
+        self._dev = tango_create_device_proxy(dev_name)
+        
+    def read_attribute(self, attr_name):
+        return tango_read_attribute(self._dev, attr_name)
+
+    def write_attribute(self, attr_name, value):
+        return tango_read_attribute(self._dev, attr)
+        
+    def read_attributes(self, attr_name_list):
+        return tango_read_attributes(self._dev, attr_name_list)
+        
+    def get_property(self, attr_name_list):
+        if isinstance(attr_name_list, str):
+            attr_name_list = [ attr_name_list ]
+        n = len(attr_name_list)
+        db_data = DbData()
+        db_data.length = n
+        db_data.sequence = (n*DbDatum)()
+        for i in xrange(n):
+            db_data.sequence[i].property_name = attr_name_list[i]
+            db_data.sequence[i].data_type = DEV_STRING
+        return tango_get_device_property(self._dev, db_data)
+
+    def __del__(self):
+        try:
+            if self._dev:
+                try:
+                    tango_delete_device_proxy(self._dev)
+                except Exception, e:
+                    print e
+        except AttributeError:
+            #The error was in the constructor and therefore _dev is not defined
+            pass
+
diff --git a/cPyTango/enumeration.py b/cPyTango/enumeration.py
new file mode 100644
index 0000000..006bea6
--- /dev/null
+++ b/cPyTango/enumeration.py
@@ -0,0 +1,109 @@
+################################################################################
+##
+## This file is part of Taurus, a Tango User Interface Library
+## 
+## http://www.tango-controls.org/static/PyTango/latest/doc/html/index.html
+##
+## Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
+## 
+## PyTango is free software: you can redistribute it and/or modify
+## it under the terms of the GNU Lesser General Public License as published by
+## the Free Software Foundation, either version 3 of the License, or
+## (at your option) any later version.
+## 
+## PyTango is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU Lesser General Public License for more details.
+## 
+## You should have received a copy of the GNU Lesser General Public License
+## along with PyTango.  If not, see <http://www.gnu.org/licenses/>.
+##
+################################################################################
+
+import types
+
+""" 
+  Enumeration module.
+  In C, enums allow you to declare a bunch of constants with unique values,
+  without necessarily specifying the actual values (except in cases where you
+  need to). Python has an accepted idiom that's fine for very small numbers of
+  constants (A, B, C, D = range(4)) but it doesn't scale well to large numbers,
+  and it doesn't allow you to specify values for some constants while leaving
+  others unspecified. This approach does those things, while verifying that all
+  values (specified and unspecified) are unique. Enum values then are attributes
+  of an Enumeration class (Volkswagen.BEETLE, Volkswagen.PASSAT, etc.).
+"""
+    
+
+class Enumeration:
+    """ Enumeration class intended to provide the 'enum' feature present in many 
+        programming languages.
+        Usage:
+        car = ThingWithType(Volkswagen.BEETLE)
+        print whatkind(car.type, Volkswagen)
+        bug = ThingWithType(Insect.BEETLE)
+        print whatkind(bug.type, Insect)
+
+        Notice that car's and bug's attributes don't include any of the
+        enum machinery, because that machinery is all CLASS attributes and
+        not INSTANCE attributes. So you can generate thousands of cars and
+        bugs with reckless abandon, never worrying that time or memory will
+        be wasted on redundant copies of the enum stuff.
+
+        print car.__dict__
+        print bug.__dict__
+        pprint.pprint(Volkswagen.__dict__)
+        pprint.pprint(Insect.__dict__)
+        """
+        
+    def __init__(self, name, enumList):
+        self.__doc__ = name
+        lookup = { }
+        reverseLookup = { }
+        uniqueNames = [ ]
+        self._uniqueValues = uniqueValues = [ ]
+        self._uniqueId = 0
+        for x in enumList:
+            if type(x) == types.TupleType:
+                x, i = x
+                if type(x) != types.StringType:
+                    raise EnumException, "enum name is not a string: " + x
+                if type(i) != types.IntType:
+                    raise EnumException, "enum value is not an integer: " + i
+                if x in uniqueNames:
+                    raise EnumException, "enum name is not unique: " + x
+                if i in uniqueValues:
+                    raise EnumException, "enum value is not unique for " + x
+                uniqueNames.append(x)
+                uniqueValues.append(i)
+                lookup[x] = i
+                reverseLookup[i] = x
+        for x in enumList:
+            if type(x) != types.TupleType:
+                if type(x) != types.StringType:
+                    raise EnumException, "enum name is not a string: " + x
+                if x in uniqueNames:
+                    raise EnumException, "enum name is not unique: " + x
+                uniqueNames.append(x)
+                i = self.generateUniqueId()
+                uniqueValues.append(i)
+                lookup[x] = i
+                reverseLookup[i] = x
+        self.lookup = lookup
+        self.reverseLookup = reverseLookup
+   
+    def generateUniqueId(self):
+        while self._uniqueId in self._uniqueValues:
+            self._uniqueId += 1
+        n = self._uniqueId
+        self._uniqueId += 1
+        return n
+    
+    def __getattr__(self, attr):
+        if not self.lookup.has_key(attr):
+            raise AttributeError
+        return self.lookup[attr]
+    
+    def whatis(self, value):
+        return self.reverseLookup[value]
diff --git a/doc/_static/banner.png b/doc/_static/banner.png
new file mode 100644
index 0000000..67ec30d
Binary files /dev/null and b/doc/_static/banner.png differ
diff --git a/doc/_static/logo-medium.png b/doc/_static/logo-medium.png
new file mode 100644
index 0000000..c47a7f5
Binary files /dev/null and b/doc/_static/logo-medium.png differ
diff --git a/doc/_static/logo.png b/doc/_static/logo.png
new file mode 100644
index 0000000..696c926
Binary files /dev/null and b/doc/_static/logo.png differ
diff --git a/doc/_templates/index.html b/doc/_templates/index.html
new file mode 100644
index 0000000..b2eec92
--- /dev/null
+++ b/doc/_templates/index.html
@@ -0,0 +1,48 @@
+{% extends "layout.html" %}
+{% set title = 'PyTango documentation' %}
+{% block body %}
+
+<h1>Welcome to PyTango documentation!</h1>
+
+<p>
+    PyTango is a python module that exposes to <a class="reference external" href="http://www.python.org/">Python</a>
+    the complete <a class="reference external" href="http://www.tango-controls.org/">Tango</a> C++ API
+    (including both client and server).
+
+</p>
+
+<p>
+    This means that you can write not only tango applications (scripts, CLIs, GUIs)
+    that access tango device servers but also tango device servers themselves, all
+    of this in pure python.
+</p>
+
+<div class="figure align-center">
+<img alt="ITango" src="_static/banner.png" style="width: 70%;" />
+</div>
+
+<p>
+    Check out the <a class="reference internal" href="start.html#getting-started"><em>getting started guide</em></a>
+    to learn how to build and/or install PyTango and after that the <a class="reference internal" href="quicktour.html#quick-tour"><em>quick tour</em></a>
+    can help you with the first steps in the PyTango world.
+</p>
+
+<p>
+    If you need help understanding what Tango itself really is, you can check the
+    <a class="reference external" href="http://www.tango-controls.org/">Tango</a>
+    homepage where you will find plenty of documentation, FAQ and tutorials.
+</p>
+
+<p>
+    A PDF version can be downloaded from <a href="PyTango.pdf">here</a>.
+</p>
+<p>
+    For convenience here are the links to other versions:<br/>
+    <a href="http://www.tango-controls.org/static/PyTango/development/doc/html">Development</a>
+     
+    <a href="http://www.tango-controls.org/static/PyTango/latest/doc/html">Latest stable</a>
+     
+    <a href="http://www.tango-controls.org/static/PyTango/v723/doc/html">7.2.3</a>
+</p>
+
+{% endblock %}
diff --git a/doc/_templates/indexsidebar.html b/doc/_templates/indexsidebar.html
new file mode 100644
index 0000000..5a9747d
--- /dev/null
+++ b/doc/_templates/indexsidebar.html
@@ -0,0 +1,12 @@
+<h3>Download</h3>
+<p>Current version: <b>{{ version }}</b></p>
+<p>Get PyTango from the <a href="http://pypi.python.org/pypi/PyTango">PyPi</a>,
+or install it with:</p>
+<pre>easy_install -U PyTango</pre>
+
+<h3>PDF</h3>
+<p>A PDF version <a href="PyTango.pdf">here</a>.
+
+<h3>Development</h3>
+<p>Latest <a href="http://www.tango-controls.org/static/PyTango/development/doc/html">development version docs</a>
+are also available.</p>
diff --git a/doc/conf.py b/doc/conf.py
index 69f2a65..0443ce7 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -33,7 +33,8 @@
 # All configuration values have a default; values that are commented out
 # serve to show the default.
 
-import sys, os
+import sys
+import os
 import re
 import PyTango
 
@@ -49,11 +50,15 @@ sys.path.append(os.path.abspath('sphinxext'))
 extensions = ['sphinx.ext.pngmath',
               'sphinx.ext.autodoc',
               'sphinx.ext.doctest',
-              'sphinx.ext.graphviz',
               'sphinx.ext.intersphinx',
               'ipython_console_highlighting',
               'tango_console_highlighting']
 
+# disable until graphviz works in pyhon 3
+if sys.hexversion < 0x03000000:
+    extensions.append('sphinx.ext.graphviz')
+
+
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
 
@@ -64,7 +69,7 @@ source_suffix = '.rst'
 #source_encoding = 'utf-8'
 
 # The master toctree document.
-master_doc = 'index'
+master_doc = 'contents'
 
 # General information about the project.
 project = u'PyTango'
@@ -139,14 +144,14 @@ html_theme = 'default'
 
 # The name for this set of Sphinx documents.  If None, it defaults to
 # "<project> v<release> documentation".
-#html_title = None
+#html_title = "PyTango documentation"
 
 # A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
+#html_short_title = "PyTango"
 
 # The name of an image file (relative to this directory) to place at the top
 # of the sidebar.
-html_logo = 'logo.png'
+html_logo = '_static/logo.png'
 
 # The name of an image file (within the static path) to use as favicon of the
 # docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
@@ -167,11 +172,11 @@ html_static_path = ['_static']
 #html_use_smartypants = True
 
 # Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
+html_sidebars = {'index': ['indexsidebar.html']}
 
 # Additional templates that should be rendered to pages, maps page names to
 # template names.
-#html_additional_pages = {}
+html_additional_pages = { 'index' : 'index.html' }
 
 # If false, no module index is generated.
 #html_use_modindex = True
@@ -214,13 +219,18 @@ latex_font_size = '10pt'
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
-  ('index', 'PyTango.tex', u'PyTango Documentation',
+  ('contents', 'PyTango.tex', u'PyTango Documentation',
    u'PyTango team', 'manual'),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
 # the title page.
-latex_logo = 'logo.png'
+latex_logo = '_static/logo.png'
+
+latex_elements = {
+    'fontpkg': '\\usepackage{palatino}',
+}
+latex_show_urls = 'footnote'
 
 # For "manual" documents, if this is true, then toplevel headings are parts,
 # not chapters.
@@ -241,6 +251,7 @@ intersphinx_mapping = {
     'http://docs.python.org/dev': None,
     'http://docs.scipy.org/doc/scipy/reference' : None,
     'http://docs.scipy.org/doc/numpy' : None,
+    'http://ipython.org/ipython-doc/stable/' : None,
 }
 
 def copy_spaces(origin):
diff --git a/doc/contents.rst b/doc/contents.rst
index 91f3c81..524f5c2 100644
--- a/doc/contents.rst
+++ b/doc/contents.rst
@@ -11,6 +11,7 @@ Contents
     :maxdepth: 2
 
     start
+    quicktour
     itango/index
     API <api>
     faq
@@ -18,4 +19,7 @@ Contents
     
 * :ref:`genindex`
 * :ref:`modindex`
-* :ref:`search`
\ No newline at end of file
+* :ref:`search`
+
+**Last update:** |today|
+
diff --git a/doc/faq.rst b/doc/faq.rst
index aec878b..d3b4908 100644
--- a/doc/faq.rst
+++ b/doc/faq.rst
@@ -268,7 +268,7 @@ In order to tell tango the dimensions of the image you had to specify them as::
     dim_y = 2
     attr.set_value(image, dim_x, dim_y)
 
-In PyTango7 it is still supported, but the preferred way is to use a
+In PyTango 8 it is still supported, but the preferred way is to use a
 sequence of sequences (instead of a flat sequence), so the dimensions
 are inherent and not needed anymore::
 
@@ -305,16 +305,16 @@ This is what you would do with PyTango <= 3.0.4::
     print "flatList =", flatList
     # flatList = [ 1, 2, 3, 4 ]
 
-You can still do it with PyTango7. However I recommend::
+You can still do it with PyTango 8. However I recommend::
 
     image = attr.get_write_value()
     print "image =", image
     # image = numpy.array([[1, 2], [3, 4]])
 
-If PyTango7 is compiled without numpy support, you will get a sequence
+If PyTango 8 is compiled without numpy support, you will get a sequence
 of sequences, which makes more sense than a flat list.
 
-If PyTango7 is compiled with numpy support it does not only makes more sense
+If PyTango 8 is compiled with numpy support it does not only makes more sense
 but it is also considerably **faster and memory friendlier**.
 
 If PyTango is compiled with numpy support but you prefer a list of lists for
diff --git a/doc/index.rst b/doc/index.rst
deleted file mode 100644
index 820bb56..0000000
--- a/doc/index.rst
+++ /dev/null
@@ -1,41 +0,0 @@
-.. PyTango documentation master file, created by
-    sphinx-quickstart on Fri Jun  5 14:31:50 2009.
-    You can adapt this file completely to your liking, but it should at least
-    contain the root `toctree` directive.
-
-.. highlight:: python
-   :linenothreshold: 4
-
-Welcome to PyTango |version| documentation!
-===========================================
-
-PyTango is a python module that exposes to Python_ the complete Tango_ C++ API
-(including both client and server).
-
-This means that you can write not only tango applications (scripts, CLIs, GUIs) 
-that access tango device servers but also tango device servers themselves, all 
-of this in pure Python_.
-
-.. figure:: itango/itango05.png
-    :width: 700
-    :align: center
-    :alt: ITango
-
-Check out the :ref:`getting started guide<getting-started>` to learn how to
-build and/or install PyTango and after that the :ref:`quick tour <quick-tour>` 
-can help you with the first steps in the PyTango world.
-
-If you need help understanding what Tango itself really is, you can check the
-Tango_ homepage where you will find plenty of documentation, faq and tutorials.
-
-.. toctree::
-    :hidden:
-
-    contents
-
-    
-:Last Update: |today|
-
-.. _Python: http://www.python.org/
-.. _IPython: http://ipython.scipy.org/
-.. _Tango: http://www.tango-controls.org/
\ No newline at end of file
diff --git a/doc/itango/Screenshot.png b/doc/itango/Screenshot.png
deleted file mode 100644
index 326e1a8..0000000
Binary files a/doc/itango/Screenshot.png and /dev/null differ
diff --git a/doc/itango/highlights.rst b/doc/itango/highlights.rst
index d8d4f0c..bfd12a1 100644
--- a/doc/itango/highlights.rst
+++ b/doc/itango/highlights.rst
@@ -16,28 +16,28 @@ These include:
       
       .. sourcecode:: itango
 
-            ITango <homer:10000> [1]: PyTango
-                         Result [1]: <module 'PyTango' from ...>
+            ITango [1]: PyTango
+            Result [1]: <module 'PyTango' from ...>
                          
     - The :class:`DeviceProxy` (=Device), :class:`AttributeProxy` (=Attribute),
       :class:`Database` and :class:`Group` classes
       
       .. sourcecode:: itango
 
-            ITango <homer:10000> [1]: De<tab>
+            ITango [1]: De<tab>
             DeprecationWarning            Device       DeviceProxy
 
-            ITango <homer:10000> [2]: Device
-                         Result [2]: <class 'PyTango._PyTango.DeviceProxy'>
+            ITango [2]: Device
+            Result [2]: <class 'PyTango._PyTango.DeviceProxy'>
             
-            ITango <homer:10000> [3]: Device("sys/tg_test/1")
-                         Result [3]: DeviceProxy(sys/tg_test/1)
+            ITango [3]: Device("sys/tg_test/1")
+            Result [3]: DeviceProxy(sys/tg_test/1)
                          
-            ITango <homer:10000> [4]: Datab<tab>
+            ITango [4]: Datab<tab>
             
-            ITango <homer:10000> [4]: Database
+            ITango [4]: Database
             
-            ITango <homer:10000> [4]: Att<tab>
+            ITango [4]: Att<tab>
             Attribute       AttributeError  AttributeProxy
             
     - The tango :class:`PyTango.Database` object to which the itango session is 
@@ -45,8 +45,8 @@ These include:
       
       .. sourcecode:: itango
 
-            ITango <homer:10000> [1]: db
-                         Result [1]: Database(homer, 10000)
+            ITango [1]: db
+            Result [1]: Database(homer, 10000)
     
 Device name completion
 ----------------------
@@ -57,13 +57,13 @@ tango database. This means that when you try to create a new Device, by pressing
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: test = Device("<tab>
+    ITango [1]: test = Device("<tab>
     Display all 3654 possibilities? (y or n) n
     
-    ITango <homer:10000> [1]: test = Device("sys<tab>
+    ITango [1]: test = Device("sys<tab>
     sys/access_control/1  sys/database/2        sys/tautest/1         sys/tg_test/1
     
-    ITango <homer:10000> [2]: test = Device("sys/tg_test/1")
+    ITango [2]: test = Device("sys/tg_test/1")
 
 Attribute name completion
 -------------------------
@@ -73,10 +73,10 @@ where the attribute resides is running.
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: short_scalar = Attribute("sys<tab>
+    ITango [1]: short_scalar = Attribute("sys<tab>
     sys/access_control/1/  sys/database/2/        sys/tautest/1/         sys/tg_test/1/
     
-    ITango <homer:10000> [1]: short_scalar = Attribute("sys/tg_test/1/<tab>
+    ITango [1]: short_scalar = Attribute("sys/tg_test/1/<tab>
     sys/tg_test/1/State                sys/tg_test/1/no_value
     sys/tg_test/1/Status               sys/tg_test/1/short_image
     sys/tg_test/1/ampli                sys/tg_test/1/short_image_ro
@@ -90,9 +90,9 @@ where the attribute resides is running.
     sys/tg_test/1/double_scalar        sys/tg_test/1/string_image_ro
     ...
 
-    ITango <homer:10000> [1]: short_scalar = Attribute("sys/tg_test/1/short_scalar")
+    ITango [1]: short_scalar = Attribute("sys/tg_test/1/short_scalar")
     
-    ITango <homer:10000> [29]: print test.read()
+    ITango [29]: print test.read()
     DeviceAttribute[
     data_format = PyTango._PyTango.AttrDataFormat.SCALAR
       dim_x = 1
@@ -121,9 +121,9 @@ and attributes if the device is currently running)
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: test = Device("sys/tg_test/1")
+    ITango [1]: test = Device("sys/tg_test/1")
     
-    ITango <homer:10000> [2]: test.<tab>
+    ITango [2]: test.<tab>
     Display all 240 possibilities? (y or n)
     ...
     test.DevVoid                            test.get_access_control
@@ -133,14 +133,14 @@ and attributes if the device is currently running)
     test.SwitchStates                       test.get_attribute_list
     ...
     
-    ITango <homer:10000> [2]: test.short_<tab>
+    ITango [2]: test.short_<tab>
     test.short_image        test.short_scalar       test.short_scalar_rww   test.short_spectrum
     test.short_image_ro     test.short_scalar_ro    test.short_scalar_w     test.short_spectrum_ro
 
-    ITango <homer:10000> [2]: test.short_scalar        # old style: test.read_attribute("short_scalar").value
-                 Result [2]: 252
+    ITango [2]: test.short_scalar        # old style: test.read_attribute("short_scalar").value
+    Result [2]: 252
 
-    ITango <homer:10000> [3]: test.Dev<tab>
+    ITango [3]: test.Dev<tab>
     test.DevBoolean               test.DevUShort                test.DevVarShortArray
     test.DevDouble                test.DevVarCharArray          test.DevVarStringArray
     test.DevFloat                 test.DevVarDoubleArray        test.DevVarULongArray
@@ -149,8 +149,8 @@ and attributes if the device is currently running)
     test.DevString                test.DevVarLongArray          
     test.DevULong                 test.DevVarLongStringArray
     
-    ITango <homer:10000> [3]: test.DevDouble(56.433)  # old style: test.command_inout("DevDouble").
-                 Result [3]: 56.433
+    ITango [3]: test.DevDouble(56.433)  # old style: test.command_inout("DevDouble").
+    Result [3]: 56.433
 
 Tango classes as :class:`DeviceProxy`
 ---------------------------------------------
@@ -161,7 +161,7 @@ This way, if you want to create a device of class which you already know
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: lib01 = Libera("BO01/DI/BPM-01")
+    ITango [1]: lib01 = Libera("BO01/DI/BPM-01")
 
 One great advantage is that the tango device name completion is sensitive to the
 type of device you want to create. This means that if you are in the middle of
@@ -170,7 +170,7 @@ class 'Libera' will show up as possible completions.
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: bpm1 = Libera("<tab>
+    ITango [1]: bpm1 = Libera("<tab>
     BO01/DI/BPM-01  BO01/DI/BPM-09  BO02/DI/BPM-06  BO03/DI/BPM-03  BO03/DI/BPM-11  BO04/DI/BPM-08
     BO01/DI/BPM-02  BO01/DI/BPM-10  BO02/DI/BPM-07  BO03/DI/BPM-04  BO04/DI/BPM-01  BO04/DI/BPM-09
     BO01/DI/BPM-03  BO01/DI/BPM-11  BO02/DI/BPM-08  BO03/DI/BPM-05  BO04/DI/BPM-02  BO04/DI/BPM-10
@@ -180,13 +180,50 @@ class 'Libera' will show up as possible completions.
     BO01/DI/BPM-07  BO02/DI/BPM-04  BO03/DI/BPM-01  BO03/DI/BPM-09  BO04/DI/BPM-06  
     BO01/DI/BPM-08  BO02/DI/BPM-05  BO03/DI/BPM-02  BO03/DI/BPM-10  BO04/DI/BPM-07
 
-    ITango <homer:10000> [1]: bpm1 = Libera("BO01<tab>
+    ITango [1]: bpm1 = Libera("BO01<tab>
     BO01/DI/BPM-01  BO01/DI/BPM-03  BO01/DI/BPM-05  BO01/DI/BPM-07  BO01/DI/BPM-09  BO01/DI/BPM-11
     BO01/DI/BPM-02  BO01/DI/BPM-04  BO01/DI/BPM-06  BO01/DI/BPM-08  BO01/DI/BPM-10
     
-    ITango <homer:10000> [1]: bpm1 = Libera("BO01/DI/BPM-
+    ITango [1]: bpm1 = Libera("BO01/DI/BPM-01")
+
+Customized device representation
+--------------------------------
+
+When you use ipython >= 0.11 with a Qt console frontend::
+
+    $ itango qtconsole
     
+typing a variable containing a tango device object followend by :kbd:`Enter`
+will present you with a customized representation of the object instead of the
+usual :func:`repr` :
+
+    .. image:: itango06.png
+
+You can customize the icon that itango displays for a specific device.
+The first thing to do is to copy the image file into
+:mod:`PyTango.ipython.resource` installation directory (if you don't have
+permissions to do so, copy the image into a directory of your choosing
+and make sure it is accessible from itango).
+
+If you want to use the image for all devices of a certain tango class, just
+add a new tango class property called *__icon*. You can do it with jive or, of
+course, with itango itself::
+
+    db.put_class_property("Libera", dict(__icon="libera.png"))
+    
+    # if you placed your image in a directory different than PyTango.ipython.resource
+    # then, instead you have to specify the absolute directory
     
+    db.put_class_property("Libera", dict(__icon="/home/homer/.config/itango/libera.png"))
+
+If you need different images for different devices of the same class, you can
+specify an *__icon* property at the device level (which takes precedence over
+the class property value, if defined)::
+
+    db.put_device_property("BO01/DI/BPM-01", dict(__icon="libera2.png"))
+
+
+
 List tango devices, classes, servers
 --------------------------------------
 
@@ -196,7 +233,7 @@ current database.
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: lsdev
+    ITango [1]: lsdev
                                       Device                     Alias                    Server                Class
     ---------------------------------------- ------------------------- ------------------------- --------------------
                   expchan/BL99_Dummy0DCtrl/1                  BL99_0D1                 Pool/BL99      ZeroDExpChannel
@@ -219,7 +256,7 @@ current database.
                  expchan/BL99_UxTimerCtrl1/1                BL99_Timer                 Pool/BL99         CTExpChannel
     ...
     
-    ITango <homer:10000> [1]: lsdevclass
+    ITango [1]: lsdevclass
     SimuCoTiCtrl                   TangoAccessControl             ZeroDExpChannel
     Door                           Motor                          DataBase
     MotorGroup                     IORegister                     SimuMotorCtrl
@@ -227,7 +264,7 @@ current database.
     SimuMotor                      SimuCounterEx                  MeasurementGroup
     Pool                           CTExpChannel
 
-    ITango <homer:10000> [1]: lsserv
+    ITango [1]: lsserv
     MacroServer/BL99               MacroServer/BL98               Pool/V2
     Pool/BL99                      Pool/BL98                      TangoTest/test
     Pool/tcoutinho                 Simulator/BL98
@@ -245,13 +282,13 @@ the magic command 'tango_error'.
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: test = Device("sys/tg_test/1")
+    ITango [1]: test = Device("sys/tg_test/1")
 
-    ITango <homer:10000> [2]: test.no_value
+    ITango [2]: test.no_value
     API_AttrValueNotSet : Read value for attribute no_value has not been updated
     For more detailed information type: tango_error
 
-    ITango <homer:10000> [3]: tango_error
+    ITango [3]: tango_error
     Last tango error:
     DevFailed[
     DevError[
@@ -273,7 +310,7 @@ command.
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: switchdb
+    ITango [1]: switchdb
 
     Must give new database name in format <host>[:<port>].
     <port> is optional. If not given it defaults to 10000.
@@ -283,11 +320,23 @@ command.
     switchdb homer 10005
     switchdb homer
     
-    ITango <homer:10000> [2]: switchdb bart       # by default port is 10000
+    ITango [2]: db
+    Database(homer, 10000)
+    
+    ITango [3]: switchdb bart       # by default port is 10000
     
-    ITango <bart:10000> [3]: switchdb lisa 10005  # you can use spaces between host and port
+    ITango [4]: db
+    Database(bart, 10000)
     
-    ITango <lisa:10005> [4]: switchdb marge:10005 # or the traditional ':'
+    ITango [5]: switchdb lisa 10005  # you can use spaces between host and port
+    
+    ITango [6]: db
+    Database(lisa, 10005)
+
+    ITango [7]: switchdb marge:10005   # or the traditional ':'
+
+    ITango [8]: db
+    Database(marge, 10005)
 
 Refreshing the database
 --------------------------
@@ -303,7 +352,7 @@ all tango information from the database.
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: refreshdb
+    ITango [1]: refreshdb
     
 Storing your favorite tango objects for later usage
 -------------------------------------------------------
@@ -320,18 +369,18 @@ then store these for the next time you startup IPython_ with itango profile.
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: theta = Motor("BL99_M1")  # notice how we used tango alias
+    ITango [1]: theta = Motor("BL99_M1")  # notice how we used tango alias
     
-    ITango <homer:10000> [2]: store theta
+    ITango [2]: store theta
     Stored 'theta' (DeviceProxy)
     
-    ITango <homer:10000> [3]: Ctrl+D
+    ITango [3]: Ctrl+D
     
     (IPython session is closed and started again...)
 
-    ITango <homer:10000> [1]: store -r # in some versions of IPython you may need to do this ...
+    ITango [1]: store -r # in some versions of IPython you may need to do this ...
     
-    ITango <homer:10000> [1]: print theta
+    ITango [1]: print theta
     DeviceProxy(motor/bl99/1)
 
 Adding itango to your own ipython profile
@@ -370,9 +419,9 @@ The way to do this is by editing your default ipython configuration file:
     
     .. sourcecode:: itango
 
-        ITango <homer:10000> [1]: import IPython.utils.path
+        ITango [1]: import IPython.utils.path
         
-        ITango <homer:10000> [2]: IPython.utils.path.get_ipython_dir()
+        ITango [2]: IPython.utils.path.get_ipython_dir()
         <IPYTHON_DIR>
 
     now edit <IPYTHON_DIR>/profile_default/ipython_config.py and add the
@@ -387,7 +436,6 @@ The way to do this is by editing your default ipython configuration file:
         extensions = getattr(i_shell_app, 'extensions', [])
         extensions.append('PyTango.ipython')
         i_shell_app.extensions = extensions
-        i_shell_app.ignore_old_config=True
     
     for more information on how to configure IPython >= 0.11 please check the
     `IPython configuration <http://ipython.org/ipython-doc/dev/config/ipython.html#configuring-the-ipython-command-line-application>`_
@@ -529,7 +577,7 @@ Here is the code for the $HOME/.ipython/ipy_profile_orbit.py:
 
 Then start your CLI with::
 
-    ipython -p orbit
+    $ ipython --profile=orbit
 
 and you will have something like this
 
@@ -549,14 +597,14 @@ To start monitoring the change events of an attribute:
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: mon -a BL99_M1/Position
+    ITango [1]: mon -a BL99_M1/Position
     'BL99_M1/Position' is now being monitored. Type 'mon' to see all events
     
 To list all events that have been intercepted:
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [2]: mon
+    ITango [2]: mon
       ID           Device    Attribute            Value       Quality             Time
     ---- ---------------- ------------ ---------------- ------------- ----------------
        0     motor/bl99/1        state               ON    ATTR_VALID  17:11:08.026472
@@ -578,7 +626,7 @@ To list all events that have been intercepted:
       16     motor/bl99/1     position            100.0    ATTR_ALARM  17:12:13.738136
       17     motor/bl99/1        state            ALARM    ATTR_VALID  17:12:13.743481
 
-    ITango <homer:10000> [3]: mon -l mot.* state
+    ITango [3]: mon -l mot.* state
       ID           Device    Attribute            Value       Quality             Time
     ---- ---------------- ------------ ---------------- ------------- ----------------
        0     motor/bl99/1        state               ON    ATTR_VALID  17:11:08.026472
@@ -589,23 +637,11 @@ To stop monitoring the attribute:
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: mon -d BL99_M1/Position
+    ITango [1]: mon -d BL99_M1/Position
     Stopped monitoring 'BL99_M1/Position'
 
 .. note::
     Type 'mon?' to see detailed information about this magic command
 
-.. warning::
-     
-    Experimental: The monitor table can be shown in a GUI. For this feature to 
-    be available you need two things:
-
-        #. Have PyQt4 (>= 4.1) installed
-        #. Start itango with '-q4thread' support: 'ipython -q4thread -p itango'
-
-    When you type '%mon' the following table should appear:
-
-        .. image:: itango04.png
-
 .. _IPython: http://ipython.org/
 .. _Tango: http://www.tango-controls.org/
diff --git a/doc/itango/index.rst b/doc/itango/index.rst
index 7de75a1..3a6cd05 100644
--- a/doc/itango/index.rst
+++ b/doc/itango/index.rst
@@ -11,20 +11,19 @@ IPython profile.
 
 ITango is available since PyTango 7.1.2
 
-You can start ITango by typing on the command line:
+You can start ITango by typing on the command line::
 
-    #. For ipython <= 0.10::
-        
-        $ ipython -p tango
+    $ itango
 
-    #. For ipython > 0.10::
+or the equivalent::
 
-        $ ipython --profile=tango
+    $ ipython --profile=tango
 
 and you should get something like this:
 
 .. image:: itango00.png
     :align: center
+    :width: 75%
 
 .. toctree::
     :maxdepth: 1
@@ -35,4 +34,4 @@ and you should get something like this:
 --------------------------------------------------------------------------------
 
 .. _IPython: http://ipython.org/
-.. _Tango: http://www.tango-controls.org/
\ No newline at end of file
+.. _Tango: http://www.tango-controls.org/
diff --git a/doc/itango/itango00.png b/doc/itango/itango00.png
index 02d4a6a..3c0e542 100644
Binary files a/doc/itango/itango00.png and b/doc/itango/itango00.png differ
diff --git a/doc/itango/itango06.png b/doc/itango/itango06.png
new file mode 100644
index 0000000..60d346d
Binary files /dev/null and b/doc/itango/itango06.png differ
diff --git a/doc/logo-medium.bmp b/doc/logo-medium.bmp
index f8c1684..74252be 100644
Binary files a/doc/logo-medium.bmp and b/doc/logo-medium.bmp differ
diff --git a/doc/logo-medium.png b/doc/logo-medium.png
deleted file mode 100644
index 7bc4cc0..0000000
Binary files a/doc/logo-medium.png and /dev/null differ
diff --git a/doc/logo.png b/doc/logo.png
deleted file mode 100644
index 06b4527..0000000
Binary files a/doc/logo.png and /dev/null differ
diff --git a/doc/man/itango.1 b/doc/man/itango.1
new file mode 100644
index 0000000..da57541
--- /dev/null
+++ b/doc/man/itango.1
@@ -0,0 +1,21 @@
+.TH ITANGO "1" "September 2012" "ITango 8.0.0" "User Commands"
+.SH NAME
+PyTango \- manual page for ITango 8.0.0
+.SH SYNOPSIS
+.B usage:
+\fIitango \fR[\fIIPython options\fR]
+.SH "SEE ALSO"
+The documentation for
+.B IPython
+
+The full documentation for
+.B ITango
+is maintained as a Texinfo manual.  If the
+.B info
+and
+.B ITango
+programs are properly installed at your site, the command
+.IP
+.B info itango
+.PP
+should give you access to the complete manual.
diff --git a/doc/quicktour.rst b/doc/quicktour.rst
index 874be64..ec51701 100644
--- a/doc/quicktour.rst
+++ b/doc/quicktour.rst
@@ -1,57 +1,54 @@
 .. _quick-tour:
 
-A quick tour
-------------
+Quick tour
+============
 
 This quick tour will guide you through the first steps on using PyTango.
 This is the new quick tour guide based on the :ref:`itango` console.
 You can still find the old version of this tour based on a simple python
 console :ref:`here <quick-tour-old>`.
 
+Quick tour on the client side
+-----------------------------
+
 Check PyTango version
 ~~~~~~~~~~~~~~~~~~~~~
 
-Start an ipython tango console with:
+Start an ipython tango console with::
 
-    #. on IPython <= 0.10:
-    
-        ipython -p tango
-        
-    #. on IPython > 0.10:
-    
-        ipython --profile=tango
+    $ itango
 
 and type:
 
     .. sourcecode:: itango
 
-        ITango <homer:10000> [1]: PyTango.__version__
-                     Result [1]: '7.1.2'
+        ITango [1]: PyTango.__version__
+        Result [1]: '8.0.0'
 
-        ITango <homer:10000> [2]: PyTango.__version_long__
-                     Result [2]: '7.1.2dev0'
+        ITango [2]: PyTango.__version_long__
+        Result [2]: '8.0.0dev0'
 
-        ITango <homer:10000> [3]: PyTango.__version_number__
-                     Result [3]: 712
+        ITango [3]: PyTango.__version_number__
+        Result [3]: 800
 
-        ITango <homer:10000> [4]: PyTango.__version_description__
-                     Result [4]: 'This version implements the C++ Tango 7.1 API.'
+        ITango [4]: PyTango.__version_description__
+        Result [4]: 'This version implements the C++ Tango 8.0 API.'
 
 or alternatively:
 
     .. sourcecode:: itango
 
-        ITango <homer:10000> [1]: PyTango.Release.version
-                     Result [1]: '7.1.2'
+        ITango [1]: PyTango.Release.version
+        Result [1]: '8.0.0'
 
-        ITango <homer:10000> [2]: PyTango.Release.version_long
-                     Result [2]: '7.1.2dev0'
+        ITango [2]: PyTango.Release.version_long
+        Result [2]: '8.0.0dev0'
 
-        ITango <homer:10000> [3]: PyTango.Release.version_number
-                     Result [3]: 712
+        ITango [3]: PyTango.Release.version_number
+        Result [3]: 800
 
-        ITango <homer:10000> [4]: PyTango.Release.version_description
-                     Result [4]: 'This version implements the C++ Tango 7.1 API.'
+        ITango [4]: PyTango.Release.version_description
+        Result [4]: 'This version implements the C++ Tango 8.0 API.'
 
 .. tip::
 
@@ -69,10 +66,10 @@ From a client (This is only possible since PyTango 7.0.0)
 
     .. sourcecode:: itango
 
-        ITango <homer:10000> [1]: import PyTango.constants
+        ITango [1]: import PyTango.constants
 
-        ITango <homer:10000> [2]: PyTango.constants.TgLibVers
-                     Result [2]: '7.1.1'
+        ITango [2]: PyTango.constants.TgLibVers
+        Result [2]: '8.0.0'
 
 From a server you can alternatively do::
     
@@ -88,8 +85,8 @@ determine if it is running or not.
 
     .. sourcecode:: itango
         
-        ITango <homer:10000> [1]: # What is a DeviceProxy, really?
-        ITango <homer:10000> [1]: DeviceProxy?
+        ITango [1]: # What is a DeviceProxy, really?
+        ITango [1]: DeviceProxy?
         DeviceProxy is the high level Tango object which provides the client with
         an easy-to-use interface to TANGO devices. DeviceProxy provides interfaces
         to all TANGO Device interfaces.The DeviceProxy manages timeouts, stateless
@@ -99,31 +96,31 @@ determine if it is running or not.
         Example :
            dev = PyTango.DeviceProxy("sys/tg_test/1")
            
-        ITango <homer:10000> [2]: tangotest = DeviceProxy("sys/tg_test/1")
+        ITango [2]: tangotest = DeviceProxy("sys/tg_test/1")
 
-        ITango <homer:10000> [3]: # ping it
-        ITango <homer:10000> [4]: tangotest.ping()
-                     Result [4]: 110
+        ITango [3]: # ping it
+        ITango [4]: tangotest.ping()
+        Result [4]: 110
 
-        ITango <homer:10000> [3]: # Lets test the state
-        ITango <homer:10000> [5]: tangotest.state()
-                     Result [5]: PyTango._PyTango.DevState.RUNNING
+        ITango [5]: # Lets test the state
+        ITango [6]: tangotest.state()
+        Result [6]: PyTango._PyTango.DevState.RUNNING
 
-        ITango <homer:10000> [3]: # And now the status
-        ITango <homer:10000> [5]: tangotest.status()
-                     Result [5]: 'The device is in RUNNING state.'
+        ITango [7]: # And now the status
+        ITango [8]: tangotest.status()
+        Result [8]: 'The device is in RUNNING state.'
 
 .. note::
     Did you notice that you didn't write PyTango.DeviceProxy but instead just
     DeviceProxy? This is because :ref:`itango` automatically exports the
-    :class:`PyTango.DeviceProxy`, :class:`PyTango.AttributeProxy`,
-    :class:`PyTango.Database` and :class:`PyTango.Group` classes to the
+    :class:`~PyTango.DeviceProxy`, :class:`~PyTango.AttributeProxy`,
+    :class:`PyTango.Database` and :class:`~PyTango.Group` classes to the
     namespace. If you are writting code outside :ref:`itango` you **MUST**
     use the `PyTango` module prefix.
 
 .. tip::
 
-    When typing the device name in the :class:`PyTango.DeviceProxy` creation
+    When typing the device name in the :class:`~PyTango.DeviceProxy` creation
     line, try pressing the <tab> key. You should get a list of devices::
     
         tangotest = DeviceProxy("sys<tab>
@@ -146,21 +143,21 @@ automatically manages the data types, and writing scripts is quite easy.
 
     .. sourcecode:: itango
     
-        ITango <homer:10000> [1]: tangotest = TangoTest("sys/tg_test/1")
+        ITango [1]: tangotest = TangoTest("sys/tg_test/1")
 
-        ITango <homer:10000> [2]: # classical way
-        ITango <homer:10000> [2]: r = tangotest.command_inout("DevString", "Hello, world!")
+        ITango [2]: # classical way
+        ITango [2]: r = tangotest.command_inout("DevString", "Hello, world!")
 
-        ITango <homer:10000> [3]: print "Result of execution of DevString command =", r
+        ITango [3]: print "Result of execution of DevString command =", r
         Result of execution of DevString command = Hello, world!
 
-        ITango <homer:10000> [4]: # 'pythonic' way
-        ITango <homer:10000> [5]: tangotest.DevString("Hello, world!")
-                     Result [5]: 'Hello, world!'
+        ITango [4]: # 'pythonic' way
+        ITango [5]: tangotest.DevString("Hello, world!")
+        Result [5]: 'Hello, world!'
         
-        ITango <homer:10000> [6]: # type is automatically managed by PyTango
-        ITango <homer:10000> [7]: tangotest.DevULong(12456)
-                     Result [7]: 12456
+        ITango [6]: # type is automatically managed by PyTango
+        ITango [7]: tangotest.DevULong(12456)
+        Result [7]: 12456
 
 Execute commands with more complex types
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -170,12 +167,12 @@ structures.
 
     .. sourcecode:: itango
     
-        ITango <homer:10000> [1]: tangotest = TangoTest("sys/tg_test/1")
+        ITango [1]: tangotest = TangoTest("sys/tg_test/1")
 
-        ITango <homer:10000> [2]: argin = [1, 2, 3], ["Hello", "World"]
+        ITango [2]: argin = [1, 2, 3], ["Hello", "World"]
 
-        ITango <homer:10000> [3]: tango_test.DevVarLongArray(argin)
-                     Result [3]: [array([1, 2, 3]), ['Hello', 'World']]
+        ITango [3]: tango_test.DevVarLongArray(argin)
+        Result [3]: [array([1, 2, 3]), ['Hello', 'World']]
         
 .. note::
     notice that the command returns a list of two elements. The first element is
@@ -190,8 +187,8 @@ Basic read/write attribute operations.
 
     .. sourcecode:: itango
     
-        ITango <homer:10000> [1]: # Read a scalar attribute
-        ITango <homer:10000> [2]: print tangotest.read_attribute("long_scalar")
+        ITango [1]: # Read a scalar attribute
+        ITango [2]: print tangotest.read_attribute("long_scalar")
         DeviceAttribute[
         data_format = PyTango._PyTango.AttrDataFormat.SCALAR
               dim_x = 1
@@ -211,8 +208,8 @@ Basic read/write attribute operations.
         w_dimension = AttributeDimension(dim_x = 1, dim_y = 0)
             w_value = 0]
             
-        ITango <homer:10000> [3]: # Read a spectrum attribute
-        ITango <pc151:10000> [4]: print tangotest.read_attribute("double_spectrum")
+        ITango [3]: # Read a spectrum attribute
+        ITango [4]: print tangotest.read_attribute("double_spectrum")
         DeviceAttribute[
         data_format = PyTango._PyTango.AttrDataFormat.SPECTRUM
               dim_x = 20
@@ -234,18 +231,18 @@ Basic read/write attribute operations.
             w_value = array([  0.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.,
                 11.,  12.,  13.,  14.,  15.,  16.,  17.,  18.,  19.])]
 
-        ITango <homer:10000> [5]: # Write a scalar attribute
-        ITango <homer:10000> [6]: scalar_value = 18
-        ITango <homer:10000> [7]: tangotest.write_attribute("long_scalar", scalar_value)
+        ITango [5]: # Write a scalar attribute
+        ITango [6]: scalar_value = 18
+        ITango [7]: tangotest.write_attribute("long_scalar", scalar_value)
 
-        ITango <homer:10000> [8]: # Write a spectrum attribute
-        ITango <homer:10000> [9]: spectrum_value = numpy.random.rand(100)*10
-        ITango <homer:10000> [10]: tangotest.write_attribute("double_spectrum", spectrum_value)
+        ITango [8]: # Write a spectrum attribute
+        ITango [9]: spectrum_value = numpy.random.rand(100)*10
+        ITango [10]: tangotest.write_attribute("double_spectrum", spectrum_value)
         
         
-        ITango <homer:10000> [11]: # Write an image attribute
-        ITango <homer:10000> [12]: image_value = numpy.random.randint(0,10,size=(10,10))
-        ITango <homer:10000> [13]: tangotest.write_attribute("long_image", image_value)
+        ITango [11]: # Write an image attribute
+        ITango [12]: image_value = numpy.random.randint(0,10,size=(10,10))
+        ITango [13]: tangotest.write_attribute("long_image", image_value)
 
 .. tip::
     
@@ -253,14 +250,14 @@ Basic read/write attribute operations.
     
     .. sourcecode:: itango
         
-            ITango <homer:10000> [1]: tangotest.long_scalar
-                         Result [1]: 239
+            ITango [1]: tangotest.long_scalar
+            Result [1]: 239
     
     The same is valid for writting a new value to an attribute:
     
     .. sourcecode:: itango
         
-            ITango <homer:10000> [1]: tangotest.long_scalar = 18
+            ITango [1]: tangotest.long_scalar = 18
     
 .. note::
 
@@ -288,28 +285,28 @@ Defining devices in the Tango DataBase:
 
     .. sourcecode:: itango
     
-        ITango <homer:10000> [1]: # The 3 devices name we want to create
-        ITango <homer:10000> [2]: # Note: these 3 devices will be served by the same DServer
-        ITango <homer:10000> [3]: new_device_name1="px1/tdl/mouse1"
-        ITango <homer:10000> [4]: new_device_name2="px1/tdl/mouse2"
-        ITango <homer:10000> [5]: new_device_name3="px1/tdl/mouse3"
+        ITango [1]: # The 3 devices name we want to create
+        ITango [2]: # Note: these 3 devices will be served by the same DServer
+        ITango [3]: new_device_name1="px1/tdl/mouse1"
+        ITango [4]: new_device_name2="px1/tdl/mouse2"
+        ITango [5]: new_device_name3="px1/tdl/mouse3"
 
-        ITango <homer:10000> [6]: # Define the Tango Class served by this DServer
-        ITango <homer:10000> [7]: new_device_info_mouse = PyTango.DbDevInfo()
-        ITango <homer:10000> [8]: new_device_info_mouse._class = "Mouse"
-        ITango <homer:10000> [9]: new_device_info_mouse.server = "ds_Mouse/server_mouse"
+        ITango [6]: # Define the Tango Class served by this DServer
+        ITango [7]: new_device_info_mouse = PyTango.DbDevInfo()
+        ITango [8]: new_device_info_mouse._class = "Mouse"
+        ITango [9]: new_device_info_mouse.server = "ds_Mouse/server_mouse"
 
-        ITango <homer:10000> [10]: # add the first device
-        ITango <homer:10000> [11]: new_device_info_mouse.name = new_device_name1
-        ITango <homer:10000> [12]: db.add_device(new_device_info_mouse)
+        ITango [10]: # add the first device
+        ITango [11]: new_device_info_mouse.name = new_device_name1
+        ITango [12]: db.add_device(new_device_info_mouse)
 
-        ITango <homer:10000> [13]: # add the next device
-        ITango <homer:10000> [14]: new_device_info_mouse.name = new_device_name2
-        ITango <homer:10000> [15]: db.add_device(new_device_info_mouse)
+        ITango [13]: # add the next device
+        ITango [14]: new_device_info_mouse.name = new_device_name2
+        ITango [15]: db.add_device(new_device_info_mouse)
 
-        ITango <homer:10000> [16]: # add the third device
-        ITango <homer:10000> [17]: new_device_info_mouse.name = new_device_name3
-        ITango <homer:10000> [18]: db.add_device(new_device_info_mouse)
+        ITango [16]: # add the third device
+        ITango [17]: new_device_info_mouse.name = new_device_name3
+        ITango [18]: db.add_device(new_device_info_mouse)
 
 Setting up Device properties
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -321,91 +318,92 @@ API should be accessed from Python.
 
     .. sourcecode:: itango
     
-        ITango <homer:10000> [1]: # connecting to the motor axis device
-        ITango <homer:10000> [2]: axis1 = DeviceProxy ("microxas/motorisation/galilbox")
-
-        ITango <homer:10000> [3]: # Getting Device Properties
-        ITango <homer:10000> [4]: property_names = ["AxisBoxAttachement",
-                           ....:                   "AxisEncoderType",
-                           ....:                   "AxisNumber",
-                           ....:                   "CurrentAcceleration",
-                           ....:                   "CurrentAccuracy",
-                           ....:                   "CurrentBacklash",
-                           ....:                   "CurrentDeceleration",
-                           ....:                   "CurrentDirection",
-                           ....:                   "CurrentMotionAccuracy",
-                           ....:                   "CurrentOvershoot",
-                           ....:                   "CurrentRetry",
-                           ....:                   "CurrentScale",
-                           ....:                   "CurrentSpeed",
-                           ....:                   "CurrentVelocity",
-                           ....:                   "EncoderMotorRatio",
-                           ....:                   "logging_level",
-                           ....:                   "logging_target",
-                           ....:                   "UserEncoderRatio",
-                           ....:                   "UserOffset"]
-        
-        ITango <homer:10000> [5]: axis_properties = axis1.get_property(property_names)
-        ITango <homer:10000> [6]: for prop in axis_properties.keys():
-                           ....:     print "%s: %s" % (prop, axis_properties[prop][0])
-
-        ITango <homer:10000> [7]: # Changing Properties
-        ITango <homer:10000> [8]: axis_properties["AxisBoxAttachement"] = ["microxas/motorisation/galilbox"]
-        ITango <homer:10000> [9]: axis_properties["AxisEncoderType"] = ["1"]
-        ITango <homer:10000> [10]: axis_properties["AxisNumber"] = ["6"]
-        ITango <homer:10000> [11]: axis1.put_property(axis_properties)
-
-        ITango <homer:10000> [12]: # Reading attributes
-        ITango <homer:10000> [13]: att_list = axis.get_attribute_list()
-        ITango <homer:10000> [14]: for att in att_list:
-                            ....:     att_val = axis.read_attribute(att)
-                            ....:     print "%s: %s" % (att.name, att_val.value)
-
-        ITango <homer:10000> [15]: # Changing some attribute values
-        ITango <homer:10000> [16]: axis1.write_attribute("AxisBackslash", 0.5)
-        ITango <homer:10000> [17]: axis1.write_attribute("AxisDirection", 1.0)
-        ITango <homer:10000> [18]: axis1.write_attribute("AxisVelocity", 1000.0)
-        ITango <homer:10000> [19]: axis1.write_attribute("AxisOvershoot", 500.0)
-
-        ITango <homer:10000> [20]: # Testing some device commands
-        ITango <homer:10000> [21]: pos1=axis1.read_attribute("AxisCurrentPosition")
-        ITango <homer:10000> [22]: axis1.command_inout("AxisBackward")
-        ITango <homer:10000> [23]: while pos1.value > 1000.0:
-                            ....:     pos1 = axis1.read_attribute("AxisCurrentPosition")
-                            ....:     print "position axis 1 = ", pos1.value
+        ITango [1]: # connecting to the motor axis device
+        ITango [2]: axis1 = DeviceProxy ("microxas/motorisation/galilbox")
+
+        ITango [3]: # Getting Device Properties
+        ITango [4]: property_names = ["AxisBoxAttachement",
+              ....:                   "AxisEncoderType",
+              ....:                   "AxisNumber",
+              ....:                   "CurrentAcceleration",
+              ....:                   "CurrentAccuracy",
+              ....:                   "CurrentBacklash",
+              ....:                   "CurrentDeceleration",
+              ....:                   "CurrentDirection",
+              ....:                   "CurrentMotionAccuracy",
+              ....:                   "CurrentOvershoot",
+              ....:                   "CurrentRetry",
+              ....:                   "CurrentScale",
+              ....:                   "CurrentSpeed",
+              ....:                   "CurrentVelocity",
+              ....:                   "EncoderMotorRatio",
+              ....:                   "logging_level",
+              ....:                   "logging_target",
+              ....:                   "UserEncoderRatio",
+              ....:                   "UserOffset"]
+       
+        ITango [5]: axis_properties = axis1.get_property(property_names)
+        ITango [6]: for prop in axis_properties.keys():
+              ....:     print "%s: %s" % (prop, axis_properties[prop][0])
+
+        ITango [7]: # Changing Properties
+        ITango [8]: axis_properties["AxisBoxAttachement"] = ["microxas/motorisation/galilbox"]
+        ITango [9]: axis_properties["AxisEncoderType"] = ["1"]
+        ITango [10]: axis_properties["AxisNumber"] = ["6"]
+        ITango [11]: axis1.put_property(axis_properties)
+
+        ITango [12]: # Reading attributes
+        ITango [13]: att_list = axis.get_attribute_list()
+        ITango [14]: for att in att_list:
+               ....:     att_val = axis.read_attribute(att)
+               ....:     print "%s: %s" % (att.name, att_val.value)
+
+        ITango [15]: # Changing some attribute values
+        ITango [16]: axis1.write_attribute("AxisBackslash", 0.5)
+        ITango [17]: axis1.write_attribute("AxisDirection", 1.0)
+        ITango [18]: axis1.write_attribute("AxisVelocity", 1000.0)
+        ITango [19]: axis1.write_attribute("AxisOvershoot", 500.0)
+
+        ITango [20]: # Testing some device commands
+        ITango [21]: pos1=axis1.read_attribute("AxisCurrentPosition")
+        ITango [22]: axis1.command_inout("AxisBackward")
+        ITango [23]: while pos1.value > 1000.0:
+               ....:     pos1 = axis1.read_attribute("AxisCurrentPosition")
+               ....:     print "position axis 1 = ", pos1.value
                             
-        ITango <homer:10000> [24]: axis1.command_inout("AxisStop")
-
-A quick tour of Tango device server binding through an example
---------------------------------------------------------------
-
-To write a tango device server in python, you need to import two modules in your script which are:
+        ITango [24]: axis1.command_inout("AxisStop")
 
-1. The PyTango module
+Quick tour on the server side
+-----------------------------
 
-2. The python sys module provided in the classical python distribution
+To write a tango device server in python, you must first import the
+:mod:`PyTango` module in your code.
 
-The following in the python script for a Tango device server with two commands and two attributes. The commands are:
+Below is the python code for a Tango device server with two commands and two
+attributes. The commands are:
 
-1. IOLOng which receives a Tango Long and return it multiply by 2. This command is allowed only if the device is in the ON state.
+1. IOLOng which receives a Tango Long and return it multiply by 2. This command
+   is allowed only if the device is in the ON state.
 
-2. IOStringArray which receives an array of Tango strings and which returns it but in the reverse order. This command is only allowed if the device is in the ON state.
+2. IOStringArray which receives an array of Tango strings and which returns it
+   but in the reverse order. This command is only allowed if the device is in
+   the ON state.
 
 The attributes are:
 
-1. Long_attr wich is a Tango long attribute, Scalar and Read only with a minimum alarm set to 1000 and a maximum alarm set to 1500
+1. Long_attr wich is a Tango long attribute, Scalar and Read only with a
+   minimum alarm set to 1000 and a maximum alarm set to 1500
 
 2. Short_attr_rw which is a Tango short attribute, Scalar and Read/Write
 
 The following code is the complete device server code::
 
     import PyTango
-    import sys
 
-    class PyDsExp(PyTango.Device_3Impl):
+    class PyDsExp(PyTango.Device_4Impl):
 
         def __init__(self,cl,name):
-            PyTango.Device_3Impl.__init__(self,cl,name)
+            PyTango.Device_4Impl.__init__(self,cl,name)
             self.debug_stream('In PyDsExp __init__')
             PyDsExp.init_device(self)
 
@@ -415,14 +413,12 @@ The following code is the complete device server code::
             self.attr_short_rw = 66
             self.attr_long = 1246
 
-    #------------------------------------------------------------------
-
         def delete_device(self):
             self.debug_stream('[delete_device] for device %s ' % self.get_name())
 
-    #------------------------------------------------------------------
-    # COMMANDS
-    #------------------------------------------------------------------
+        #------------------------------------------------------------------
+        # COMMANDS
+        #------------------------------------------------------------------
 
         def is_IOLong_allowed(self):
             return self.get_state() == PyTango.DevState.ON
@@ -433,8 +429,6 @@ The following code is the complete device server code::
             self.debug_stream('[IOLong::execute] return number %s' % str(in_data))
             return in_data;
 
-    #------------------------------------------------------------------
-
         def is_IOStringArray_allowed(self):
             return self.get_state() == PyTango.DevState.ON
 
@@ -450,58 +444,32 @@ The following code is the complete device server code::
             self.y = out_data
             return out_data
 
-    #------------------------------------------------------------------
-    # ATTRIBUTES
-    #------------------------------------------------------------------
+        #------------------------------------------------------------------
+        # ATTRIBUTES
+        #------------------------------------------------------------------
 
         def read_attr_hardware(self, data):
             self.debug_stream('In read_attr_hardware')
 
-    #------------------------------------------------------------------
-
         def read_Long_attr(self, the_att):
             self.debug_stream('[PyDsExp::read_attr] attribute name Long_attr')
-
-            # Before PyTango 7.0.0
-            #PyTango.set_attribute_value(the_att, self.attr_long)
-
-            # Now:
             the_att.set_value(self.attr_long)
 
-    #------------------------------------------------------------------
-
         def read_Short_attr_rw(self, the_att):
             self.debug_stream('[PyDsExp::read_attr] attribute name Short_attr_rw')
-
-            # Before PyTango 7.0.0
-            #PyTango.set_attribute_value(the_att, self.attr_short_rw)
-            
-            # Now:
             the_att.set_value(self.attr_short_rw)
 
-    #------------------------------------------------------------------
-
         def write_Short_attr_rw(self, the_att):
             self.debug_stream('In write_Short_attr_rw for attribute %s' % the_att.get_name())
-
-            # Before PyTango 7.0.0
-            #data = []
-            #PyTango.get_write_value(the_att, data)
-
-            # Now:
             data = the_att.get_write_value()
             self.attr_short_rw = data[0]
 
-    #------------------------------------------------------------------
-    # CLASS
-    #------------------------------------------------------------------
-
+    
     class PyDsExpClass(PyTango.DeviceClass):
 
         def __init__(self, name):
             PyTango.DeviceClass.__init__(self, name)
-            self.set_type("TestDevice")
-            print 'In PyDsExpClass __init__'
+            self.set_type("PyDsExp")
 
         cmd_list = { 'IOLong' : [ [ PyTango.ArgType.DevLong, "Number" ],
                                   [ PyTango.ArgType.DevLong, "Number * 2" ] ],
@@ -518,21 +486,17 @@ The following code is the complete device server code::
                                            PyTango.AttrDataFormat.SCALAR,
                                            PyTango.AttrWriteType.READ_WRITE ] ]
         }
+    
+    
+    def main():
+        PyTango.server_run({"PyDsExp" : (PyDsExpClass, PyDsExp)})
 
     if __name__ == '__main__':
-        try:
-            util = PyTango.Util(sys.argv)
-            
-            # 
-            # Deprecated: util.add_TgClass(PyDsExpClass, PyDsExp, 'PyDsExp')
-            util.add_class(PyDsExpClass, PyDsExp, 'PyDsExp')
-            
-            U = PyTango.Util.instance()
-            U.server_init()
-            U.server_run()
-        except PyTango.DevFailed,e:
-            print '-------> Received a DevFailed exception:',e
-        except Exception,e:
-            print '-------> An unforeseen exception occured....',e
-
-.. _IPython: http://ipython.scipy.org/
\ No newline at end of file
+        main()
+
+.. toctree::
+    :hidden:
+
+    Quick tour (original) <quicktour_old>
+    
+.. _IPython: http://ipython.scipy.org/
diff --git a/doc/revision.rst b/doc/revision.rst
index 5dc866d..cea73b0 100644
--- a/doc/revision.rst
+++ b/doc/revision.rst
@@ -65,6 +65,8 @@ History of modifications:
 +----------+----------------------------------------------------------------------------------+-----------------------------------------------------+-----------------------+
 | 24/04/12 | `8.13 <http://www.tango-controls.org/static/PyTango/v723/doc/html/index.html>`_  | Update to PyTango 7.2.3                             | T\. Coutinho          |
 +----------+----------------------------------------------------------------------------------+-----------------------------------------------------+-----------------------+
+|   /09/12 | `8.14 <http://www.tango-controls.org/static/PyTango/v800/doc/html/index.html>`_  | Update to PyTango 8.0.0                             | T\. Coutinho          |
++----------+----------------------------------------------------------------------------------+-----------------------------------------------------+-----------------------+
 
 .. _version-history:
 
@@ -74,6 +76,16 @@ Version history
 +------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 | version    | Changes                                                                                                                                                                      |
 +============+==============================================================================================================================================================================+
+| 8.0.0      | Features:                                                                                                                                                                    |
+|            |     - Implemented tango C++ 8.0 API                                                                                                                                          |
+|            |     - Python 3k compatible                                                                                                                                                   |
+|            | Bug fixes:                                                                                                                                                                   |
+|            |     - from sourceforge:                                                                                                                                                      |
+|            |         - `3023857: DevEncoded write attribute not supported <https://sourceforge.net/tracker/?func=detail&aid=3023857&group_id=57612&atid=484769>`_                         |
+|            |         - `3521545: [pytango] problem with tango profile <https://sourceforge.net/tracker/?func=detail&aid=3521545&group_id=57612&atid=484769>`_                             |
+|            |         - `3530535: PyTango group writting fails <https://sourceforge.net/tracker/?func=detail&aid=3530535&group_id=57612&atid=484769>`_                                     |
+|            |         - `3564959: EncodedAttribute.encode_xxx() methods don't accept bytearray  <https://sourceforge.net/tracker/?func=detail&aid=3564959&group_id=57612&atid=484769>`_    |
++------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
 | 7.2.3      | Features:                                                                                                                                                                    |
 |            |     - from sourceforge:                                                                                                                                                      |
 |            |         - `3495607: DeviceClass.device_name_factory is missing <https://sourceforge.net/tracker/?func=detail&aid=3495607&group_id=57612&atid=484772>`_                       |
diff --git a/doc/server/index.rst b/doc/server/index.rst
index 6f9cbc8..caf5099 100644
--- a/doc/server/index.rst
+++ b/doc/server/index.rst
@@ -400,74 +400,170 @@ will be the used for the input arguments. Also, it is recomended to use numpy
 arrays of the appropiate type for output arguments as well, as it is much more
 efficient.
 
-+-------------------------+-------------------------------------------------------------------+
-|   Tango data type       |              Python type                                          |
-+=========================+===================================================================+
-|          DEV_VOID       |                    No data                                        |
-+-------------------------+-------------------------------------------------------------------+
-|       DEV_BOOLEAN       | :py:obj:`bool`                                                    |
-+-------------------------+-------------------------------------------------------------------+
-|         DEV_SHORT       | :py:obj:`int`                                                     |
-+-------------------------+-------------------------------------------------------------------+
-|         DEV_LONG        | :py:obj:`int`                                                     |
-+-------------------------+-------------------------------------------------------------------+
-|        DEV_LONG64       | :py:obj:`long` (on a 32 bits computer) or                         |
-|                         | :py:obj:`int` (on a 64 bits computer)                             |
-+-------------------------+-------------------------------------------------------------------+
-|         DEV_FLOAT       | :py:obj:`float`                                                   |
-+-------------------------+-------------------------------------------------------------------+
-|       DEV_DOUBLE        | :py:obj:`float`                                                   |
-+-------------------------+-------------------------------------------------------------------+
-|        DEV_USHORT       | :py:obj:`int`                                                     |
-+-------------------------+-------------------------------------------------------------------+
-|        DEV_ULONG        | :py:obj:`int`                                                     |
-+-------------------------+-------------------------------------------------------------------+
-|        DEV_ULONG64      | :py:obj:`long` (on a 32 bits computer) or                         |
-|                         | :py:obj:`int` (on a 64 bits computer)                             |
-+-------------------------+-------------------------------------------------------------------+
-|        DEV_STRING       | :py:obj:`str`                                                     |
-+-------------------------+-------------------------------------------------------------------+
-|    DEVVAR_CHARARRAY     | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint8`) or       |
-|                         | sequence<:py:obj:`int`>                                           |
-+-------------------------+-------------------------------------------------------------------+
-|    DEVVAR_SHORTARRAY    | :py:class:`numpy.ndarray` (dtype=:py:obj:`numpy.int16`) or        |
-|                         | sequence<:py:obj:`int`>                                           |
-+-------------------------+-------------------------------------------------------------------+
-|    DEVVAR_LONGARRAY     | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.int32`) or       |
-|                         | sequence<:py:obj:`int`>                                           |
-+-------------------------+-------------------------------------------------------------------+
-|   DEVVAR_LONG64ARRAY    | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.int64`) or       |
-|                         | sequence<:py:obj:`long`> (on a 32 bits computer) or               |
-|                         | sequence<:py:obj:`int`> (on a 64 bits computer)                   |
-+-------------------------+-------------------------------------------------------------------+
-|    DEVVAR_FLOATARRAY    | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float32`) or     |
-|                         | sequence<:py:obj:`float`>                                         |
-+-------------------------+-------------------------------------------------------------------+
-|   DEVVAR_DOUBLEARRAY    | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float64`) or     |
-|                         | sequence<:py:obj:`float`>                                         |
-+-------------------------+-------------------------------------------------------------------+
-|   DEVVAR_USHORTARRAY    | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint16`) or      |
-|                         | sequence<:py:obj:`int`>                                           |
-+-------------------------+-------------------------------------------------------------------+
-|   DEVVAR_ULONGARRAY     | numpy.ndarray(dtype= :py:obj:`numpy.uint32`) or                   |
-|                         | sequence<:py:obj:`int`>                                           |
-+-------------------------+-------------------------------------------------------------------+
-|  DEVVAR_ULONG64ARRAY    | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint64`) or      |
-|                         | sequence<:py:obj:`long`> (on a 32 bits computer) or               |
-|                         | sequence<:py:obj:`int`> (on a 64 bits computer)                   |
-+-------------------------+-------------------------------------------------------------------+
-|   DEVVAR_STRINGARRAY    | sequence<:py:obj:`str`>                                           |
-+-------------------------+-------------------------------------------------------------------+
-|                         | A sequence with two elements:                                     |
-| DEVVAR_LONGSTRINGARRAY  |  1. :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.int32`) or   |
-|                         |     sequence<:py:obj:`int`>                                       |
-|                         |  2. sequence<:py:obj:`str`>                                       |
-+-------------------------+-------------------------------------------------------------------+
-|                         | A sequence with two elements:                                     |
-|DEVVAR_DOUBLESTRINGARRAY |  1. :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float64`) or |
-|                         |     sequence<:py:obj:`float`>                                     |
-|                         |  2. sequence<:py:obj:`str`>                                       |
-+-------------------------+-------------------------------------------------------------------+
+**For scalar types**
+
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|   Tango data type       |              Python 2.x type                                              |              Python 3.x type (*New in PyTango 8.0*)                       |
++=========================+===========================================================================+===========================================================================+
+|          DEV_VOID       |                    No data                                                |                    No data                                                |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|       DEV_BOOLEAN       | :py:obj:`bool`                                                            | :py:obj:`bool`                                                            |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|         DEV_SHORT       | :py:obj:`int`                                                             | :py:obj:`int`                                                             |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|         DEV_LONG        | :py:obj:`int`                                                             | :py:obj:`int`                                                             |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|        DEV_LONG64       | - :py:obj:`long` (on a 32 bits computer)                                  | :py:obj:`int`                                                             |
+|                         | - :py:obj:`int` (on a 64 bits computer)                                   |                                                                           |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|         DEV_FLOAT       | :py:obj:`float`                                                           | :py:obj:`float`                                                           |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|       DEV_DOUBLE        | :py:obj:`float`                                                           | :py:obj:`float`                                                           |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|        DEV_USHORT       | :py:obj:`int`                                                             | :py:obj:`int`                                                             |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|        DEV_ULONG        | :py:obj:`int`                                                             | :py:obj:`int`                                                             |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|        DEV_ULONG64      | * :py:obj:`long` (on a 32 bits computer)                                  | :py:obj:`int`                                                             |
+|                         | * :py:obj:`int` (on a 64 bits computer)                                   |                                                                           |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|        DEV_STRING       | :py:obj:`str`                                                             | :py:obj:`str` (decoded with *latin-1*, aka *ISO-8859-1*)                  |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | sequence of two elements:                                                 | sequence of two elements:                                                 |
+| DEV_ENCODED             |                                                                           |                                                                           |
+| (*New in PyTango 8.0*)  | 0. :py:obj:`str`                                                          | 0. :py:obj:`str` (decoded with *latin-1*, aka *ISO-8859-1*)               |
+|                         | 1. :py:obj:`bytes` (for any value of *extract_as*)                        | 1. :py:obj:`bytes` (for any value of *extract_as*, except String.         |
+|                         |                                                                           |    In this case it is :py:obj:`str` (decoded with default python          |
+|                         |                                                                           |    encoding *utf-8*))                                                     |
++-------------------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+
+**For array types**
+
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|    Tango data type      |   ExtractAs     |                          Data type (Python 2.x)                           |             Data type (Python 3.x) (*New in PyTango 8.0*)                 |
++=========================+=================+===========================================================================+===========================================================================+
+| DEVVAR_CHARARRAY        | Numpy           | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint8`)                  | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint8`)                  |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Bytes           | :py:obj:`bytes` (which is in fact equal to :py:obj:`str`)                 | :py:obj:`bytes`                                                           |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | ByteArray       | :py:obj:`bytearray`                                                       | :py:obj:`bytearray`                                                       |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | String          | :py:obj:`str`                                                             | String    :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | List            | :py:class:`list` <:py:obj:`int`>                                          | :py:class:`list` <:py:obj:`int`>                                          |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Tuple           | :py:class:`tuple` <:py:obj:`int`>                                         | :py:class:`tuple` <:py:obj:`int`>                                         |
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEVVAR_SHORTARRAY       | Numpy           | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint16`)                 | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint16`)                 |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Bytes           | :py:obj:`bytes` (which is in fact equal to :py:obj:`str`)                 | :py:obj:`bytes`                                                           |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | ByteArray       | :py:obj:`bytearray`                                                       | :py:obj:`bytearray`                                                       |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | String          | :py:obj:`str`                                                             | String    :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | List            | :py:class:`list` <:py:obj:`int`>                                          | :py:class:`list` <:py:obj:`int`>                                          |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Tuple           | :py:class:`tuple` <:py:obj:`int`>                                         | :py:class:`tuple` <:py:obj:`int`>                                         |
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEVVAR_LONGARRAY        | Numpy           | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint32`)                 | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint32`)                 |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Bytes           | :py:obj:`bytes` (which is in fact equal to :py:obj:`str`)                 | :py:obj:`bytes`                                                           |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | ByteArray       | :py:obj:`bytearray`                                                       | :py:obj:`bytearray`                                                       |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | String          | :py:obj:`str`                                                             | String    :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | List            | :py:class:`list` <:py:obj:`int`>                                          | :py:class:`list` <:py:obj:`int`>                                          |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Tuple           | :py:class:`tuple` <:py:obj:`int`>                                         | :py:class:`tuple` <:py:obj:`int`>                                         |
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEVVAR_LONG64ARRAY      | Numpy           | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint64`)                 | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint64`)                 |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Bytes           | :py:obj:`bytes` (which is in fact equal to :py:obj:`str`)                 | :py:obj:`bytes`                                                           |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | ByteArray       | :py:obj:`bytearray`                                                       | :py:obj:`bytearray`                                                       |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | String          | :py:obj:`str`                                                             | String    :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | List            | :py:class:`list` <int (64 bits) / long (32 bits)>                         | :py:class:`list` <:py:obj:`int`>                                          |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Tuple           | :py:class:`tuple` <int (64 bits) / long (32 bits)>                        | :py:class:`tuple` <:py:obj:`int`>                                         |
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEVVAR_FLOATARRAY       | Numpy           | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float32`)                | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float32`)                |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Bytes           | :py:obj:`bytes` (which is in fact equal to :py:obj:`str`)                 | :py:obj:`bytes`                                                           |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | ByteArray       | :py:obj:`bytearray`                                                       | :py:obj:`bytearray`                                                       |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | String          | :py:obj:`str`                                                             | String    :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | List            | :py:class:`list` <:py:obj:`float`>                                        | :py:class:`list` <:py:obj:`float`>                                        |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Tuple           | :py:class:`tuple` <:py:obj:`float`>                                       | :py:class:`tuple` <:py:obj:`float`>                                       |
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEVVAR_DOUBLEARRAY      | Numpy           | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float64`)                | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float64`)                |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Bytes           | :py:obj:`bytes` (which is in fact equal to :py:obj:`str`)                 | :py:obj:`bytes`                                                           |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | ByteArray       | :py:obj:`bytearray`                                                       | :py:obj:`bytearray`                                                       |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | String          | :py:obj:`str`                                                             | String    :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | List            | :py:class:`list` <:py:obj:`float`>                                        | :py:class:`list` <:py:obj:`float`>                                        |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Tuple           | :py:class:`tuple` <:py:obj:`float`>                                       | :py:class:`tuple` <:py:obj:`float`>                                       |
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEVVAR_USHORTARRAY      | Numpy           | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint16`)                 | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint16`)                 |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Bytes           | :py:obj:`bytes` (which is in fact equal to :py:obj:`str`)                 | :py:obj:`bytes`                                                           |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | ByteArray       | :py:obj:`bytearray`                                                       | :py:obj:`bytearray`                                                       |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | String          | :py:obj:`str`                                                             | String    :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | List            | :py:class:`list` <:py:obj:`int`>                                          | :py:class:`list` <:py:obj:`int`>                                          |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Tuple           | :py:class:`tuple` <:py:obj:`int`>                                         | :py:class:`tuple` <:py:obj:`int`>                                         |
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEVVAR_ULONGARRAY       | Numpy           | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint32`)                 | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint32`)                 |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Bytes           | :py:obj:`bytes` (which is in fact equal to :py:obj:`str`)                 | :py:obj:`bytes`                                                           |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | ByteArray       | :py:obj:`bytearray`                                                       | :py:obj:`bytearray`                                                       |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | String          | :py:obj:`str`                                                             | String    :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | List            | :py:class:`list` <:py:obj:`int`>                                          | :py:class:`list` <:py:obj:`int`>                                          |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Tuple           | :py:class:`tuple` <:py:obj:`int`>                                         | :py:class:`tuple` <:py:obj:`int`>                                         |
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+| DEVVAR_ULONG64ARRAY     | Numpy           | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint64`)                 | :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.uint64`)                 |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Bytes           | :py:obj:`bytes` (which is in fact equal to :py:obj:`str`)                 | :py:obj:`bytes`                                                           |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | ByteArray       | :py:obj:`bytearray`                                                       | :py:obj:`bytearray`                                                       |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | String          | :py:obj:`str`                                                             | String    :py:obj:`str` (decoded with default python encoding *utf-8*!!!) |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | List            | :py:class:`list` <int (64 bits) / long (32 bits)>                         | :py:class:`list` <:py:obj:`int`>                                          |
+|                         +-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         | Tuple           | :py:class:`tuple` <int (64 bits) / long (32 bits)>                        | :py:class:`tuple` <:py:obj:`int`>                                         |
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|   DEVVAR_STRINGARRAY    |                 | sequence<:py:obj:`str`>                                                   | sequence<:py:obj:`str`> (decoded with *latin-1*, aka *ISO-8859-1*)        |
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         |                 | sequence of two elements:                                                 | sequence of two elements:                                                 |
+|  DEV_LONGSTRINGARRAY    |                 |                                                                           |                                                                           |
+|                         |                 | 0. :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.int32`) or            | 0. :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.int32`) or            |
+|                         |                 |    sequence<:py:obj:`int`>                                                |    sequence<:py:obj:`int`>                                                |
+|                         |                 | 1. sequence<:py:obj:`str`>                                                | 1.  sequence<:py:obj:`str`> (decoded with *latin-1*, aka *ISO-8859-1*)    |
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
+|                         |                 | sequence of two elements:                                                 | sequence of two elements:                                                 |
+|  DEV_DOUBLESTRINGARRAY  |                 |                                                                           |                                                                           |
+|                         |                 | 0. :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float64`) or          | 0. :py:class:`numpy.ndarray` (dtype= :py:obj:`numpy.float64`) or          |
+|                         |                 |    sequence<:py:obj:`int`>                                                |    sequence<:py:obj:`int`>                                                |
+|                         |                 | 1. sequence<:py:obj:`str`>                                                | 1. sequence<:py:obj:`str`> (decoded with *latin-1*, aka *ISO-8859-1*)     |
++-------------------------+-----------------+---------------------------------------------------------------------------+---------------------------------------------------------------------------+
 
 The following code is an example of how you write code executed when a client
 calls a command named IOLong::
diff --git a/doc/sphinxext/tango_console_highlighting.py b/doc/sphinxext/tango_console_highlighting.py
index ffff5b9..fa70aff 100644
--- a/doc/sphinxext/tango_console_highlighting.py
+++ b/doc/sphinxext/tango_console_highlighting.py
@@ -49,7 +49,7 @@ DftStyle = pygments.styles.get_style_by_name("default")
 class TangoStyle(DftStyle):
     
     styles = copy.copy(DftStyle.styles)
-    styles[Generic.Prompt] = 'bold #800080'
+    styles[Generic.Prompt] = 'bold #00AA00'
 
 class TangoConsoleLexer(Lexer):
     """
@@ -57,15 +57,15 @@ class TangoConsoleLexer(Lexer):
 
     .. sourcecode:: itango
 
-      ITango <homer:10000> [1]: a = 'foo'
+      ITango [1]: a = 'foo'
 
-      ITango <homer:10000> [2]: a
+      ITango [2]: a
                    Result [2]: 'foo'
 
-      ITango <homer:10000> [3]: print a
+      ITango [3]: print a
       foo
 
-      ITango <homer:10000> [4]: 1 / 0
+      ITango [4]: 1 / 0
 
     Notes:
 
@@ -77,7 +77,7 @@ class TangoConsoleLexer(Lexer):
     name = 'ITango console session'
     aliases = ['itango']
     mimetypes = ['text/x-itango-console']
-    input_prompt = re.compile("(ITango \<\w+:\d+\> \[(?P<N>[0-9]+)\]: )|(   \.\.\.+:)")
+    input_prompt = re.compile("(ITango \[(?P<N>[0-9]+)\]: )|(   \.\.\.+:)")
     output_prompt = re.compile("(\s*Result \[(?P<N>[0-9]+)\]: )|(   \.\.\.+:)")
     continue_prompt = re.compile("   \.\.\.+:")
     tb_start = re.compile("\-+")
@@ -136,4 +136,4 @@ def setup(app):
 
 #-----------------------------------------------------------------------------
 # Register the extension as a valid pygments lexer
-highlighting.lexers['itango'] = TangoConsoleLexer()
\ No newline at end of file
+highlighting.lexers['itango'] = TangoConsoleLexer()
diff --git a/doc/start.rst b/doc/start.rst
index aee1be9..11d29ba 100644
--- a/doc/start.rst
+++ b/doc/start.rst
@@ -26,12 +26,12 @@ Dependencies on other libraries
 
     digraph dependencies {
         size="6,3";
-        PyTango     [shape=box, label="PyTango 7.2"];
-        Python      [shape=box, label="Python >=2.4"];
+        PyTango     [shape=box, label="PyTango 8.0"];
+        Python      [shape=box, label="Python >=2.6"];
         boostpython [shape=box, label="boost python"];
         boostp1     [shape=box, label="boost >=1.33"];
         boostp2     [shape=box, label="boost >=1.41"];
-        Tango       [shape=box, label="Tango >=7.2"];
+        Tango       [shape=box, label="Tango >=8.0.5"];
         omniORB     [shape=box, label="omniORB >=4"];
         numpy       [shape=box, label="numpy >=1.1.0"];
         IPython     [shape=box, label="IPython >=0.10"];
@@ -48,9 +48,9 @@ Dependencies on other libraries
 Don't be scared by the graph. Probably most of the packages are already installed.
 The current PyTango version has four major dependencies:
 
-- python (>= 2.4) (http://www.python.org/)
+- python (>= 2.6) (http://www.python.org/)
 - omniORB (http://omniorb.sourceforge.net/)
-- Tango (>= 7.2.0) (http://www.tango-controls.org/)
+- Tango (>= 8.0.5) (http://www.tango-controls.org/)
 - boost python (http://www.boost.org):
     if python >= 2.6.3 then: boost-python >= 1.41
     else: boost-python >= 1.33
@@ -71,8 +71,8 @@ Linux
 ~~~~~
 
 The PyTango team does **not** provide a precompiled binary for Linux since this
-would mean having to provide 12 different binaries: one for each major python
-version (2.4, 2.5, 2.6, 2.7, 3.0 and 3.1) times 2 for both 32bits and 64bits.
+would mean having to provide at least 10 different binaries: one for each major
+python version (2.6, 2.7, 3.0, 3.1 and 3.2) times 2 for both 32bits and 64bits.
 
 Tango contributers have written packages for *at least* ubuntu and debian linux
 distributions. Check the **Ubuntu GNU/Linux binary distribution** chapter under
@@ -87,30 +87,32 @@ PyTango team provides a limited set of binary PyTango distributables for
 Windows XP/Vista/7. The complete list of binaries can be downloaded from
 `PyTango PyPI website <http://pypi.python.org/pypi/PyTango/>`_.
 
-.. _PyTango-7.2.2.win32-py2.6.msi: http://pypi.python.org/packages/2.6/P/PyTango/PyTango-7.2.2.win32-py2.6.msi
-.. _PyTango-7.2.2.win32-py2.6.exe: http://pypi.python.org/packages/2.6/P/PyTango/PyTango-7.2.2.win32-py2.6.exe
-.. _PyTango-7.2.2.win32-py2.7.msi: http://pypi.python.org/packages/2.7/P/PyTango/PyTango-7.2.2.win32-py2.7.msi
-.. _PyTango-7.2.2.win32-py2.7.exe: http://pypi.python.org/packages/2.7/P/PyTango/PyTango-7.2.2.win32-py2.7.exe
-
-+----------------------------------+--------------------------------------------------+----------------------------------------------+
-| version                          | Dependencies                                     | Compilation env.                             |
-+==================================+==================================================+==============================================+
-| `PyTango-7.2.2.win32-py2.6.msi`_ | - Tango C++ >= 7.2.6 and < 8.0                   | - Tango 7.2.6 windows distribution           |
-| `PyTango-7.2.2.win32-py2.6.exe`_ | - Python 2.6.x (where x >= 0)                    | - Python 2.6.6                               |
-|                                  | - numpy 1.x (where x >= 1. Recommended x >= 5)   | - Numpy 1.5                                  |
-|                                  |                                                  | - boost-python 1.41 mutithreaded dll         |
-|                                  |                                                  | - Visual Studio 8.0 (2005)                   |
-|                                  |                                                  | - Windows XP Pro 2002 SP3                    |
-|                                  |                                                  | - PC: Intel Xeon E5440 @ 2.83GHz 1GB RAM     |
-+----------------------------------+--------------------------------------------------+----------------------------------------------+
-| `PyTango-7.2.2.win32-py2.7.msi`_ | - Tango C++ >= 7.2.6 and < 8.0                   | - Tango 7.2.6 windows distribution           |
-| `PyTango-7.2.2.win32-py2.7.exe`_ | - Python 2.7.x (where x >= 0)                    | - Python 2.7.2                               |
-|                                  | - numpy 1.x (where x >= 1. Recommended x >= 5)   | - Numpy 1.5                                  |
-|                                  |                                                  | - boost-python 1.47 mutithreaded dll         |
-|                                  |                                                  | - Visual Studio 8.0 (2005)                   |
-|                                  |                                                  | - Windows XP Pro 2002 SP3                    |
-|                                  |                                                  | - PC: Intel Xeon E5440 @ 2.83GHz 1GB RAM     |
-+----------------------------------+--------------------------------------------------+----------------------------------------------+
+.. _PyTango-7.2.3.win32-py2.6.msi: http://pypi.python.org/packages/2.6/P/PyTango/PyTango-7.2.3.win32-py2.6.msi
+.. _PyTango-7.2.3.win32-py2.6.exe: http://pypi.python.org/packages/2.6/P/PyTango/PyTango-7.2.3.win32-py2.6.exe
+.. _PyTango-7.2.3.win32-py2.7.msi: http://pypi.python.org/packages/2.7/P/PyTango/PyTango-7.2.3.win32-py2.7.msi
+.. _PyTango-7.2.3.win32-py2.7.exe: http://pypi.python.org/packages/2.7/P/PyTango/PyTango-7.2.3.win32-py2.7.exe
+
+.. only:: html
+
+    +----------------------------------+--------------------------------------------------+----------------------------------------------+
+    | version                          | Dependencies                                     | Compilation env.                             |
+    +==================================+==================================================+==============================================+
+    | `PyTango-7.2.3.win32-py2.6.msi`_ | - Tango C++ >= 7.2.6 and < 8.0                   | - Tango 7.2.6 windows distribution           |
+    | `PyTango-7.2.3.win32-py2.6.exe`_ | - Python 2.6.x (where x >= 0)                    | - Python 2.6.6                               |
+    |                                  | - numpy 1.x (where x >= 1. Recommended x >= 5)   | - Numpy 1.5                                  |
+    |                                  |                                                  | - boost-python 1.41 mutithreaded dll         |
+    |                                  |                                                  | - Visual Studio 8.0 (2005)                   |
+    |                                  |                                                  | - Windows XP Pro 2002 SP3                    |
+    |                                  |                                                  | - PC: Intel Xeon E5440 @ 2.83GHz 1GB RAM     |
+    +----------------------------------+--------------------------------------------------+----------------------------------------------+
+    | `PyTango-7.2.3.win32-py2.7.msi`_ | - Tango C++ >= 7.2.6 and < 8.0                   | - Tango 7.2.6 windows distribution           |
+    | `PyTango-7.2.3.win32-py2.7.exe`_ | - Python 2.7.x (where x >= 0)                    | - Python 2.7.2                               |
+    |                                  | - numpy 1.x (where x >= 1. Recommended x >= 5)   | - Numpy 1.5                                  |
+    |                                  |                                                  | - boost-python 1.47 mutithreaded dll         |
+    |                                  |                                                  | - Visual Studio 8.0 (2005)                   |
+    |                                  |                                                  | - Windows XP Pro 2002 SP3                    |
+    |                                  |                                                  | - PC: Intel Xeon E5440 @ 2.83GHz 1GB RAM     |
+    +----------------------------------+--------------------------------------------------+----------------------------------------------+
 
 Until version 7.2.2 (due to internal incompatibilities between tango C++ API
 and PyTango), PyTango had to be shipped with an internal copy of tango and
@@ -121,13 +123,7 @@ C++ installed **and** the environment variable :envvar:`PATH` **must** include
 the directory where the tango C++ DLLs are installed (usually
 :file:`C:\\Program Files{ (x86)}\\tango\\win32_vc8\\win32_dll`).
 
-Regarding boost-python, since VS hard links with the boost-python DLL file of
-the machine where PyTango binary was originally compiled, PyTango ships with
-it's own internal copy of the boost-python DLL.
-Maybe in the future PyTango will link with the static version of boost-python
-but for now we get to many errors at compile time so we are skipping this for
-now. Anyway, it's just an internal developers detail. For you just means 250kb more
-of memory usage in windows.
+Since PyTango 7.2.3, boost-python is statically linked to avoid DLL conflicts.
 
 The binary was compiled with numpy dependency therefore you need to have *numpy*
 installed in order to use PyTango.
@@ -272,23 +268,16 @@ test
 
 If you have IPython_ installed, the best way to test your PyTango installation
 is by starting the new PyTango CLI called :ref:`itango` by typing on the command
-line:
-
-    #. IPython <= 0.10::
-
-        $ ipython -p tango
-
-    #.IPython > 0.10::
-
-        $ ipython --profile=tango
+line::
 
+    $ itango
 
 then, in ITango type:
 
 .. sourcecode:: itango
 
-    ITango <homer:10000> [1]: PyTango.Release.version
-                  Result [1]: '7.2.3'
+    ITango [1]: PyTango.Release.version
+    Result [1]: '8.0.0'
 
 (if you are wondering, :ref:`itango` automaticaly does ``import PyTango`` for you!)
 
@@ -296,13 +285,9 @@ If you don't have IPython_ installed, to test the installation start a python co
 and type:
 
     >>> import PyTango
-    >>> print PyTango.Release.version
-    7.2.3
-
-.. toctree::
-    :hidden:
+    >>> PyTango.Release.version
+    '8.0.0'
 
-    Quick tour <quicktour>
-    Quick tour (original) <quicktour_old>
     
-.. _IPython: http://ipython.scipy.org/
\ No newline at end of file
+.. _IPython: http://ipython.scipy.org/
+
diff --git a/doc/title.png b/doc/title.png
deleted file mode 100644
index e11cda8..0000000
Binary files a/doc/title.png and /dev/null differ
diff --git a/doc/utilities.rst b/doc/utilities.rst
index 26152c9..962e8dd 100644
--- a/doc/utilities.rst
+++ b/doc/utilities.rst
@@ -3,6 +3,9 @@
 The Utilities API
 =================
 
+.. autofunction:: PyTango.server_run
+
+
 .. currentmodule:: PyTango.utils
 
 .. autoclass:: PyTango.utils.EventCallBack
diff --git a/PyTango/ipython/ipython_00_12/__init__.py b/scripts/itango
old mode 100644
new mode 100755
similarity index 73%
rename from PyTango/ipython/ipython_00_12/__init__.py
rename to scripts/itango
index 2766c15..1547a76
--- a/PyTango/ipython/ipython_00_12/__init__.py
+++ b/scripts/itango
@@ -1,3 +1,5 @@
+#!/usr/bin/env python
+
 ################################################################################
 ##
 ## This file is part of PyTango, a python binding for Tango
@@ -21,11 +23,17 @@
 ##
 ################################################################################
 
-__all__ = ['load_ipython_extension', 'unload_ipython_extension', 'load_config',
-           'install']
-
-from PyTango.ipython.ipython_00_11 import *
+"""The itango startup file. This executable is actually an extension of the 
+   ipython file that can be found in <prefix>/ipython (prefix usually being in 
+   linux '/usr/bin'"""
 
-#rewrite 0.11's load config
-from ipython_00_12 import load_config
+__all__ = [ "main" ]
 
+__docformat__ = 'restructuredtext'
+    
+def main():
+    import PyTango.ipython
+    PyTango.ipython.run()
+    
+if __name__ == '__main__':
+    main()
diff --git a/setup.py b/setup.py
index d8d8056..0dbd527 100644
--- a/setup.py
+++ b/setup.py
@@ -25,6 +25,7 @@ import os
 import sys
 import platform
 import imp
+import io
 
 from distutils.core import setup, Extension
 from distutils.cmd import Command
@@ -39,14 +40,13 @@ try:
     import sphinx.util.console
     sphinx.util.console.color_terminal = lambda : False
     from sphinx.setup_command import BuildDoc
-except Exception,e:
-    print e
+except:
     sphinx = None
 
 try:
     import IPython
     _IPY_ROOT = os.path.dirname(os.path.abspath(IPython.__file__))
-    _IPY_VER = map(int, IPython.__version__.split(".")[:2])
+    _IPY_VER = list(map(int, IPython.__version__.split(".")[:2]))
     if _IPY_VER > [0,10]:
         import IPython.utils.path
         get_ipython_dir = IPython.utils.path.get_ipython_dir
@@ -59,7 +59,7 @@ except:
 
 try:
     import numpy
-except Exception, e:
+except:
     numpy = None
 
 
@@ -81,9 +81,20 @@ def uniquify(seq):
     [ no_dups.append(i) for i in seq if not no_dups.count(i) ]
     return no_dups
 
+def get_c_numpy():
+    NUMPY_ROOT = os.environ.get('NUMPY_ROOT')
+    if NUMPY_ROOT is not None:
+        d = os.path.join(NUMPY_ROOT, 'include','numpy')
+        if os.path.isdir(d):
+            return d
+    if numpy is None:
+        return None
+    d = os.path.join(numpy.__path__[0], 'core', 'include')
+    if os.path.isdir(d):
+        return d
+
 def has_c_numpy():
-    NUMPY_ROOT = os.environ.get('NUMPY_ROOT', '/usr')
-    return os.path.isdir(os.path.join(NUMPY_ROOT, 'include','numpy'))
+    return get_c_numpy() is not None
 
 def has_numpy(with_src=True):
     ret = numpy is not None
@@ -91,19 +102,41 @@ def has_numpy(with_src=True):
         ret &= has_c_numpy()
     return ret
 
+def get_script_files():
+    scripts_dir = abspath('scripts')
+    scripts = []
+    items = os.listdir(scripts_dir)
+    for item in items:
+        # avoid hidden files
+        if item.startswith("."):
+            continue
+        abs_item = os.path.join(scripts_dir, item)
+        # avoid non files
+        if not os.path.isfile(abs_item):
+            continue
+        # avoid files that have any extension
+        if len(os.path.splitext(abs_item)[1]) > 0:
+            continue
+        # avoid compiled version of script
+        if item.endswith('c') and item[:-1] in items:
+            continue
+        # avoid any core dump... of course there isn't any :-) but just in case
+        if item.startswith('core'):
+            continue
+        scripts.append('scripts/' + item)
+    return scripts
+
 class build(dftbuild):
     
     user_options = dftbuild.user_options + \
-        [('with-pytango3', None, "distribute PyTango3 module"),
-         ('without-ipython', None, "Tango IPython extension"),
+        [('without-ipython', None, "Tango IPython extension"),
          ('strip-lib', None, "strips the shared library of debugging symbols (Unix like systems only)"),
          ('no-doc', None, "do not build documentation") ]
     
-    boolean_options = dftbuild.boolean_options + ['with-pytango3', 'without-ipython', 'strip-lib', 'no-doc']
+    boolean_options = dftbuild.boolean_options + ['without-ipython', 'strip-lib', 'no-doc']
     
     def initialize_options (self):
         dftbuild.initialize_options(self)
-        self.with_pytango3 = None
         self.without_ipython = None
         self.strip_lib = None
         self.no_doc = None
@@ -114,10 +147,8 @@ class build(dftbuild):
     def run(self):
         if numpy is None:
             self.warn('NOT using numpy: it is not available')
-        elif not has_c_numpy():
+        elif get_c_numpy() is None:
             self.warn("NOT using numpy: numpy available but C source is not")
-        if self.with_pytango3:
-            self.distribution.packages.append('PyTango3')
         
         if IPython and not self.without_ipython:
             if _IPY_VER > [0,10]:
@@ -151,9 +182,9 @@ class build(dftbuild):
             return False
         if sphinx is None:
             return False
-        v = map(int, sphinx.__version__.split("."))
+        v = list(map(int, sphinx.__version__.split(".")))
         if v <= [0,6,5]:
-            print "Documentation will not be generated: sphinx version (%s) too low. Needs 0.6.6" % sphinx.__version__
+            print("Documentation will not be generated: sphinx version (%s) too low. Needs 0.6.6" % sphinx.__version__)
             return False 
         setup_dir = os.path.dirname(os.path.abspath(__file__))
         return os.path.isdir(os.path.join(setup_dir, 'doc'))
@@ -164,13 +195,28 @@ class build(dftbuild):
 class build_ext(dftbuild_ext): 
     
     def build_extensions(self):
+        self.use_cpp_0x = False
         if isinstance(self.compiler, UnixCCompiler):
             compiler_pars = self.compiler.compiler_so
             while '-Wstrict-prototypes' in compiler_pars:
                 del compiler_pars[compiler_pars.index('-Wstrict-prototypes')]
             #self.compiler.compiler_so = " ".join(compiler_pars)
+            
+            # mimic tango check to activate C++0x extension
+            import subprocess
+            compiler = self.compiler.compiler
+            pipe = subprocess.Popen(compiler + ["-dumpversion"], stdout=subprocess.PIPE).stdout
+            gcc_ver = pipe.readlines()[0].decode().strip().split(".")
+            gcc_ver = list(map(int, gcc_ver))
+            if gcc_ver >= [4,3,3]:
+                self.use_cpp_0x = True
         dftbuild_ext.build_extensions(self)
 
+    def build_extension(self, ext):
+        if self.use_cpp_0x:
+            ext.extra_compile_args += ['-std=c++0x']
+        dftbuild_ext.build_extension(self, ext)
+
 if sphinx:
     class build_doc(BuildDoc):
         
@@ -234,12 +280,12 @@ class install(dftinstall):
 
 
 def main():
-    BOOST_ROOT = OMNI_ROOT = TANGO_ROOT = NUMPY_ROOT = '/usr'
+    BOOST_ROOT = OMNI_ROOT = TANGO_ROOT = '/usr'
 
     TANGO_ROOT = os.environ.get('TANGO_ROOT', TANGO_ROOT)
     OMNI_ROOT  = os.environ.get('OMNI_ROOT', OMNI_ROOT)
     BOOST_ROOT = os.environ.get('BOOST_ROOT', BOOST_ROOT)
-    NUMPY_ROOT = os.environ.get('NUMPY_ROOT', NUMPY_ROOT)
+    numpy_c_include = get_c_numpy()
     
     Release = get_release_info()
 
@@ -252,7 +298,6 @@ def main():
         'PyTango.ipython',
         'PyTango.ipython.ipython_00_10',
         'PyTango.ipython.ipython_00_11',
-        'PyTango.ipython.ipython_00_12',
     ]
 
     py_modules = []
@@ -269,7 +314,9 @@ def main():
     package_data = {
         'PyTango' : [],
     }
-
+    
+    scripts = get_script_files()
+    
     data_files = []
 
     classifiers = [
@@ -307,10 +354,9 @@ def main():
     if os.path.isdir(_tango_root_inc):
         include_dirs.append(_tango_root_inc)
 
-    include_dirs.extend([
-        os.path.join(OMNI_ROOT, 'include'),
-        os.path.join(NUMPY_ROOT, 'include'),
-    ])
+    include_dirs.append(os.path.join(OMNI_ROOT, 'include'))
+    if numpy_c_include is not None:
+        include_dirs.append(numpy_c_include)
 
     #-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
     # library directories
@@ -319,6 +365,7 @@ def main():
     libraries = [
         'tango',
         'log4tango',
+        'zmq',
     ]
 
     extra_compile_args = []
@@ -402,10 +449,7 @@ def main():
         # to link against boost_python-py25/-py26 etc...
         pyver = "py" + "".join(map(str, platform.python_version_tuple()[:2]))
         dist = platform.dist()[0].lower()
-        if dist in ['debian']:
-            libraries.append('boost_python-' + pyver)
-        else:
-            libraries.append('boost_python')
+        libraries.append('boost_python-' + pyver)
 
         library_dirs += [ os.path.join(OMNI_ROOT, 'lib') ]
 
@@ -435,6 +479,7 @@ def main():
     client_dir = src_dir
     server_dir = os.path.join(src_dir, 'server')
     _clientfiles = [ os.path.join(client_dir,fname) for fname in os.listdir(client_dir) if fname.endswith('.cpp') ]
+    _clientfiles.remove(os.path.join(client_dir,"group_element.cpp"))
     _clientfiles.sort()
     _serverfiles = [ os.path.join(server_dir,fname) for fname in os.listdir(server_dir) if fname.endswith('.cpp') ]
     _serverfiles.sort()
@@ -472,11 +517,12 @@ def main():
         platforms        = Release.platform,
         license          = Release.license,
         packages         = packages,
-        package_dir      = { 'PyTango' : 'PyTango', 'PyTango3' : 'PyTango3' },
+        package_dir      = { 'PyTango' : 'PyTango' },
         py_modules       = py_modules,
         classifiers      = classifiers,
         package_data     = package_data,
         data_files       = data_files,
+        scripts          = scripts,
         provides         = provides,
         keywords         = Release.keywords,
         requires         = requires,
diff --git a/src/api_util.cpp b/src/api_util.cpp
index 6954487..d0e4651 100644
--- a/src/api_util.cpp
+++ b/src/api_util.cpp
@@ -65,7 +65,10 @@ void export_api_util()
         .def("get_env_var", &PyApiUtil::get_env_var)
         .staticmethod("get_env_var")
         
-        .def("is_event_consumer_created", &Tango::ApiUtil::is_event_consumer_created)
+        .def("is_notifd_event_consumer_created", &Tango::ApiUtil::is_notifd_event_consumer_created)
+        .def("is_zmq_event_consumer_created", &Tango::ApiUtil::is_zmq_event_consumer_created)
         .def("get_user_connect_timeout", &Tango::ApiUtil::get_user_connect_timeout)
+        
+        .def("get_ip_from_if", &Tango::ApiUtil::get_ip_from_if)
     ;
 }
diff --git a/src/attribute_info.cpp b/src/attribute_info.cpp
index d9d9f18..215ef9c 100644
--- a/src/attribute_info.cpp
+++ b/src/attribute_info.cpp
@@ -30,7 +30,7 @@ void export_attribute_info()
 {
     class_<Tango::AttributeInfo, bases<Tango::DeviceAttributeConfig> >
         ("AttributeInfo")
-        .def(init<const Tango::AttributeInfoEx&>())
+        .def(init<const Tango::AttributeInfo&>())
         .def_readwrite("disp_level", &Tango::AttributeInfo::disp_level)
     ;
 }
diff --git a/src/attribute_proxy.cpp b/src/attribute_proxy.cpp
index e708f46..1890076 100644
--- a/src/attribute_proxy.cpp
+++ b/src/attribute_proxy.cpp
@@ -25,7 +25,7 @@
 #include "defs.h"
 #include "pytgutils.h"
 
-using namespace boost::python;
+namespace bopy = boost::python;
 
 extern const char *param_must_be_seq;
 extern const char *unreachable_code;
@@ -33,15 +33,15 @@ extern const char *non_string_seq;
 
 namespace PyAttributeProxy
 {
-    struct PickleSuite : pickle_suite
+    struct PickleSuite : bopy::pickle_suite
     {
-        static tuple getinitargs(Tango::AttributeProxy& self)
+        static bopy::tuple getinitargs(Tango::AttributeProxy& self)
         {
             Tango::DeviceProxy* dev = self.get_device_proxy();
             
             std::string ret = dev->get_db_host() + ":" + dev->get_db_port() + 
                              "/" + dev->dev_name() + "/" + self.name();
-            return make_tuple(ret);
+            return bopy::make_tuple(ret);
         }
     };
 }
@@ -58,14 +58,14 @@ void export_attribute_proxy()
     void (Tango::AttributeProxy::*delete_property_)(std::string &) =
         &Tango::AttributeProxy::delete_property;
 
-    class_<Tango::AttributeProxy> AttributeProxy(
+    bopy::class_<Tango::AttributeProxy> AttributeProxy(
         "__AttributeProxy",
-        init<const char *>())
+        bopy::init<const char *>())
     ;
 
     AttributeProxy
-        .def(init<const Tango::DeviceProxy *, const char *>())
-        .def(init<const Tango::AttributeProxy &>())
+        .def(bopy::init<const Tango::DeviceProxy *, const char *>())
+        .def(bopy::init<const Tango::AttributeProxy &>())
 
         //
         // Pickle
@@ -81,7 +81,7 @@ void export_attribute_proxy()
 
         .def("get_device_proxy", &Tango::AttributeProxy::get_device_proxy,
             ( arg_("self") ),
-            return_internal_reference<1>())
+            bopy::return_internal_reference<1>())
 
         //
         // property methods
diff --git a/src/base_types.cpp b/src/base_types.cpp
index 7bf2839..b2fd009 100644
--- a/src/base_types.cpp
+++ b/src/base_types.cpp
@@ -176,30 +176,15 @@ int raise_asynch_exception(long thread_id, boost::python::object exp_klass)
     return PyThreadState_SetAsyncExc(thread_id, exp_klass.ptr());
 }
 
-bool isBufferLikeType(PyObject* obj)
-{
-#if PY_VERSION_HEX < 0x02060000
-    // Returns true for buffer
-    if (PyBuffer_Check(obj))
-        return true;
-    if (PyString_Check(obj))
-        return true;
-#else
-    // Returns true for str, buffer bytes, bytearray, memoryview
-    if (PyObject_CheckBuffer(obj))
-        return true;
-#endif
-    return false;
-}
-
 void export_base_types()
 {
     enum_<PyTango::ExtractAs>("ExtractAs")
         .value("Numpy", PyTango::ExtractAsNumpy)
+        .value("ByteArray", PyTango::ExtractAsByteArray)
+        .value("Bytes", PyTango::ExtractAsBytes)
         .value("Tuple", PyTango::ExtractAsTuple)
         .value("List", PyTango::ExtractAsList)
         .value("String", PyTango::ExtractAsString)
-        .value("PyTango3", PyTango::ExtractAsPyTango3)
         .value("Nothing", PyTango::ExtractAsNothing)
     ;
 
@@ -276,6 +261,9 @@ void export_base_types()
     class_<std::vector<Tango::DbHistory> >("DbHistoryList")
         .def(vector_indexing_suite<std::vector<Tango::DbHistory>, true>());
 
+    class_<std::vector<Tango::DeviceData> >("DeviceDataList")
+        .def(vector_indexing_suite<std::vector<Tango::DeviceData>, true>());
+
     class_<Tango::DeviceDataHistoryList>("DeviceDataHistoryList")
         .def(vector_indexing_suite<Tango::DeviceDataHistoryList, true>());
 
@@ -291,8 +279,8 @@ void export_base_types()
     class_< StdGroupAttrReplyVector_ >("StdGroupAttrReplyVector")
         .def(vector_indexing_suite<StdGroupAttrReplyVector_, true>());
 
-    //to_python_converter<CORBA::String_member, CORBA_String_member_to_str>();
-    to_python_converter<_CORBA_String_member, CORBA_String_member_to_str2>();
+    to_python_converter<CORBA::String_member, CORBA_String_member_to_str>();
+    //to_python_converter<_CORBA_String_member, CORBA_String_member_to_str2>();
     to_python_converter<_CORBA_String_element, CORBA_String_element_to_str>();
 
     to_python_converter<Tango::DevErrorList, CORBA_sequence_to_tuple<Tango::DevErrorList> >();
@@ -363,6 +351,4 @@ void export_base_types()
     export_time_val();
     
     def("raise_asynch_exception", &raise_asynch_exception);
-    
-    def("isBufferLikeType", &isBufferLikeType);
 }
diff --git a/src/connection.cpp b/src/connection.cpp
index 2317801..a8ca2c4 100644
--- a/src/connection.cpp
+++ b/src/connection.cpp
@@ -159,5 +159,6 @@ void export_connection()
         
         .def("get_access_control", &Tango::Connection::get_access_control)
         .def("set_access_control", &Tango::Connection::set_access_control)
+        .def("get_access_right", &Tango::Connection::get_access_right)
     ;
 }
diff --git a/src/constants.cpp b/src/constants.cpp
index cf31f66..99b4524 100644
--- a/src/constants.cpp
+++ b/src/constants.cpp
@@ -43,17 +43,6 @@ void export_constants()
     consts_scope.attr("NUMPY_SUPPORT") = true;
 #endif
 
-    str py_TgLibVers = TgLibVers;
-    boost::python::list pylist_TgLibVers = py_TgLibVers.split(".");
-    long_ major = long_(pylist_TgLibVers[0]);
-    long_ minor = long_(pylist_TgLibVers[1]);
-    long_ patch = long_(pylist_TgLibVers[2]);
-    object h = "0x%02d%02d%02d00" % boost::python::make_tuple(major, minor, patch);
-    PyObject *ptr = PyInt_FromString(PyString_AsString(h.ptr()), NULL, 0);
-    TANGO_VERSION_HEX = PyInt_AsLong(ptr);
-    Py_DECREF(ptr);
-    consts_scope.attr("TANGO_VERSION_HEX") = TANGO_VERSION_HEX;
-
     //
     // From tango_const.h
     //
@@ -61,6 +50,9 @@ void export_constants()
     //
     // Some general interest define
     //
+    consts_scope.attr("TANGO_VERSION_MAJOR") = TANGO_VERSION_MAJOR;
+    consts_scope.attr("TANGO_VERSION_MINOR") = TANGO_VERSION_MINOR;
+    consts_scope.attr("TANGO_VERSION_PATCH") = TANGO_VERSION_PATCH;
     
     consts_scope.attr("TgLibVers") = TgLibVers;
     consts_scope.attr("DevVersion") = DevVersion;
@@ -73,7 +65,12 @@ void export_constants()
     consts_scope.attr("DefaultDocUrl") = DefaultDocUrl;
     consts_scope.attr("EnvVariable") = EnvVariable;
     consts_scope.attr("DbObjName") = DbObjName;
-    consts_scope.attr("DescNotSet") = DescNotSet;
+    
+    // Changed in tango 8 from DescNotSet to NotSet. We keep the old constant
+    // to try to maintain backward compatibility
+    consts_scope.attr("DescNotSet") = NotSet;
+    consts_scope.attr("NotSet") = NotSet;
+    
     consts_scope.attr("ResNotDefined") = ResNotDefined;
     consts_scope.attr("MessBoxTitle") = MessBoxTitle;
     consts_scope.attr("StatusNotSet") = StatusNotSet;
@@ -195,4 +192,13 @@ void export_constants()
     consts_scope.attr("NotANumber") = NotANumber;
     consts_scope.attr("MemNotUsed") = MemNotUsed;
     consts_scope.attr("MemAttrPropName") = MemAttrPropName;
+ 
+#ifdef TANGO_LONG64
+    consts_scope.attr("TANGO_LONG32") = false;
+    consts_scope.attr("TANGO_LONG64") = true;
+#else
+    consts_scope.attr("TANGO_LONG32") = true;
+    consts_scope.attr("TANGO_LONG64") = false;
+#endif    
+
 }
diff --git a/src/database.cpp b/src/database.cpp
index d8edef7..c7b1910 100644
--- a/src/database.cpp
+++ b/src/database.cpp
@@ -25,8 +25,6 @@
 #include "defs.h"
 #include "pytgutils.h"
 
-using namespace boost::python;
-
 extern const char *param_must_be_seq;
 extern const char *unreachable_code;
 extern const char *non_string_seq;
@@ -36,18 +34,18 @@ const char *param_numb_or_str_numb = "Second parameter must be an int or a "
 
 struct PyDatabase
 {
-    struct PickleSuite : pickle_suite
+    struct PickleSuite : bopy::pickle_suite
     {
-        static tuple getinitargs(Tango::Database& self)
+        static bopy::tuple getinitargs(Tango::Database& self)
         {
             std::string& host = self.get_db_host();
             std::string& port = self.get_db_port();
             if (host.size() > 0 && port.size() > 0)
             {
-                return make_tuple(host, port);
+                return bopy::make_tuple(host, port);
             }
             else
-                return make_tuple();
+                return bopy::make_tuple();
         }
     };
     
@@ -218,16 +216,14 @@ void export_database()
     void (Tango::Database::*delete_attribute_alias_)(std::string &) =
         &Tango::Database::delete_attribute_alias;
     
-    
-    class_<Tango::Database, bases<Tango::Connection> > Database(
-        "Database",
-        init<>())
+    bopy::class_<Tango::Database, bopy::bases<Tango::Connection> > Database("Database", bopy::init<>())
     ;
 
     Database
-        .def("__init__", make_constructor(PyDatabase::makeDatabase_host_port1))
-        .def("__init__", make_constructor(PyDatabase::makeDatabase_host_port2))
-        .def("__init__", make_constructor(PyDatabase::makeDatabase_file))
+        .def(bopy::init<const Tango::Database &>())
+        .def("__init__", bopy::make_constructor(PyDatabase::makeDatabase_host_port1))
+        .def("__init__", bopy::make_constructor(PyDatabase::makeDatabase_host_port2))
+        .def("__init__", bopy::make_constructor(PyDatabase::makeDatabase_file))
 
         //
         // Pickle
@@ -249,10 +245,10 @@ void export_database()
             &Tango::Database::set_access_checked)
         .def("get_access_except_errors",
             &Tango::Database::get_access_except_errors,
-            return_internal_reference<1>())
+            bopy::return_internal_reference<1>())
         .def("is_multi_tango_host", &Tango::Database::is_multi_tango_host)
         .def("get_file_name", &Tango::Database::get_file_name,
-            return_value_policy<copy_const_reference>())
+            bopy::return_value_policy<bopy::copy_const_reference>())
             
         //
         // General methods
@@ -362,7 +358,8 @@ void export_database()
         .def("get_device_class_list",
             (Tango::DbDatum (Tango::Database::*) (const std::string &))
             get_device_class_list_)
-
+        .def("get_server_release", &Tango::Database::get_server_release)
+        
         //
         // property methods
         //
diff --git a/src/defs.h b/src/defs.h
index 0dbdbb0..b6c604f 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -30,14 +30,24 @@ typedef std::vector<std::string> StdStringVector;
 typedef std::vector<long> StdLongVector;
 typedef std::vector<double> StdDoubleVector;
 
+/* HAS_UNIQUE_PTR definition comes from tango. It tells PyTango if Tango itself
+   is using the new C++0x unique_ptr or not. In PyTango we try to use the same
+   as TangoC++ whenever possible. */
+#ifdef HAS_UNIQUE_PTR
+#define unique_pointer std::unique_ptr
+#else
+#define unique_pointer std::auto_ptr
+#endif
+
 namespace PyTango
 {
     enum ExtractAs {
         ExtractAsNumpy,
+        ExtractAsByteArray,
+        ExtractAsBytes,
         ExtractAsTuple,
         ExtractAsList,
         ExtractAsString,
-        ExtractAsPyTango3,
         ExtractAsNothing
     };
     
diff --git a/src/dev_error.cpp b/src/dev_error.cpp
index 1fb80e2..c630721 100644
--- a/src/dev_error.cpp
+++ b/src/dev_error.cpp
@@ -22,26 +22,25 @@
 *******************************************************************************/
 
 #include "precompiled_header.hpp"
+#include "pyutils.h"
 #include <tango.h>
 
-using namespace boost::python;
-
 struct PyDevError
 {
     static inline PyObject* get_reason(Tango::DevError &de)
-    { return PyString_FromString(de.reason); }
+    { return from_char_to_str(de.reason); }
 
     static inline PyObject* get_desc(Tango::DevError &de)
-    { return PyString_FromString(de.desc); }
+    { return from_char_to_str(de.desc); }
 
     static inline PyObject* get_origin(Tango::DevError &de)
-    { return PyString_FromString(de.origin); }
+    { return from_char_to_str(de.origin); }
 
 };
 
 void export_dev_error()
 {
-    class_<Tango::DevError>("DevError")
+    bopy::class_<Tango::DevError>("DevError")
         .add_property("reason", &PyDevError::get_reason)
         .def_readonly("severity", &Tango::DevError::severity)
         .add_property("desc", &PyDevError::get_desc)
diff --git a/src/device_attribute.cpp b/src/device_attribute.cpp
index 55c7445..2b7bb98 100644
--- a/src/device_attribute.cpp
+++ b/src/device_attribute.cpp
@@ -44,33 +44,35 @@ static const char* has_failed_attr_name = "has_failed";
 
 
 template<long tangoTypeConst>
-struct python_tangocpp {
+struct python_tangocpp
+{
     typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
 
-    static inline void to_cpp(const object & py_value, TangoScalarType & result)
+    static inline void to_cpp(const bopy::object & py_value, TangoScalarType & result)
     {
-        result = extract<TangoScalarType>(py_value);
+        result = bopy::extract<TangoScalarType>(py_value);
     }
 
-    static inline object to_python(const TangoScalarType & value)
+    static inline bopy::object to_python(const TangoScalarType & value)
     {
-        return object(value);
+        return bopy::object(value);
     }
 };
 
 template<>
-struct python_tangocpp<Tango::DEV_STRING> {
+struct python_tangocpp<Tango::DEV_STRING>
+{
     static const long tangoTypeConst = Tango::DEV_STRING;
     typedef TANGO_const2type(tangoTypeConst) TangoScalarType;
 
-    static inline void to_cpp(const object & py_value, TangoScalarType & result)
+    static inline void to_cpp(const bopy::object & py_value, TangoScalarType & result)
     {
-        result = CORBA::string_dup(extract<TangoScalarType>(py_value));
+        result = CORBA::string_dup(bopy::extract<TangoScalarType>(py_value));
     }
 
-    static inline object to_python(const TangoScalarType & value)
+    static inline bopy::object to_python(const TangoScalarType & value)
     {
-        return object(std::string(value));
+        return bopy::object(std::string(value));
     }
 };
 
@@ -78,175 +80,278 @@ struct python_tangocpp<Tango::DEV_STRING> {
 #   include "device_attribute_numpy.hpp"
 #endif
 
-namespace PyDeviceAttribute {
+#define EXTRACT_VALUE(self, value_ptr) \
+try { \
+    self >> value_ptr; \
+} catch (Tango::DevFailed &e ) { \
+    if (strcmp(e.errors[0].reason.in(),"API_EmptyDeviceAttribute") != 0) \
+        throw; \
+}
+    
 
-    template<long tangoTypeConst>
-    static inline void _update_value_as_string(Tango::DeviceAttribute &self, object py_value)
+namespace PyDeviceAttribute
+{
+    template<long tangoTypeConst> static inline void
+    _update_value_as_bin(Tango::DeviceAttribute &self,
+                         bopy::object py_value, bool read_only)
     {
         typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
         typedef typename TANGO_const2arraytype(tangoTypeConst) TangoArrayType;
 
         // Extract the actual data from Tango::DeviceAttribute (self)
         TangoArrayType* value_ptr = 0;
-        try {
-            self >> value_ptr;
-        } catch (Tango::DevFailed &e ) {
-            if (strcmp(e.errors[0].reason.in(),"API_EmptyDeviceAttribute") != 0)
-                throw;
-        }
-        std::auto_ptr<TangoArrayType> guard_value_ptr(value_ptr);
+        EXTRACT_VALUE(self, value_ptr)
+        unique_pointer<TangoArrayType> guard_value_ptr(value_ptr);
 
-        if (value_ptr == 0) {
-            py_value.attr(value_attr_name) = boost::python::str();
-            py_value.attr(w_value_attr_name) = object();
+        py_value.attr(w_value_attr_name) = bopy::object();
+
+        if (value_ptr == 0)
+        {
+            if (read_only)
+            {
+                py_value.attr(value_attr_name) =
+                    bopy::object(bopy::handle<>(_PyObject_New(&PyBytes_Type)));
+            }
+            else
+            {
+                py_value.attr(value_attr_name) =
+                    bopy::object(bopy::handle<>(_PyObject_New(&PyByteArray_Type)));
+            }
             return;
         }
 
         TangoScalarType* buffer = value_ptr->get_buffer();
 
         const char *ch_ptr = reinterpret_cast<char *>(buffer);
-        size_t nb_bytes = value_ptr->length() * sizeof(TangoScalarType);
+        Py_ssize_t nb_bytes = (Py_ssize_t)value_ptr->length() * sizeof(TangoScalarType);
 
-        py_value.attr(value_attr_name) = str(ch_ptr, (size_t)nb_bytes);
-        py_value.attr(w_value_attr_name) = object();
+        PyObject* data_ptr = NULL;
+        if (read_only)
+        {
+            data_ptr = PyBytes_FromStringAndSize(ch_ptr, nb_bytes);
+        }
+        else
+        {
+            data_ptr = PyByteArray_FromStringAndSize(ch_ptr, nb_bytes);
+        }
+        py_value.attr(value_attr_name) = bopy::object(bopy::handle<>(data_ptr));
     }
 
-    template<>
-    inline void _update_value_as_string<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self, object py_value)
+    template<> inline void
+    _update_value_as_bin<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self,
+                                             bopy::object py_value,
+                                             bool read_only)
     {
-        Tango::DevVarEncodedArray* value;
-        self >> value;
-        std::auto_ptr<Tango::DevVarEncodedArray> guard(value);
+        Tango::DevVarEncodedArray* value_ptr;
+        EXTRACT_VALUE(self, value_ptr)
+        unique_pointer<Tango::DevVarEncodedArray> guard(value_ptr);
         
-        Tango::DevEncoded* buffer = value->get_buffer();
+        Tango::DevEncoded* buffer = value_ptr->get_buffer();
+        Tango::DevEncoded& r_buffer = buffer[0];
+        bopy::str r_encoded_format(r_buffer.encoded_format);
         
-        boost::python::str encoded_format(buffer[0].encoded_format);
-        boost::python::str encoded_data((const char*)buffer[0].encoded_data.get_buffer(),
-                                        buffer[0].encoded_data.length());
+        Tango::DevVarCharArray& r_encoded_data_array = r_buffer.encoded_data;
+        char* r_ch_ptr = (char*) r_encoded_data_array.get_buffer();
+        Py_ssize_t r_size = r_encoded_data_array.length();
+        PyObject* r_encoded_data_ptr = NULL;
+        if (read_only)
+        {
+            r_encoded_data_ptr = PyBytes_FromStringAndSize(r_ch_ptr, r_size);
+        }
+        else
+        {
+            r_encoded_data_ptr = PyByteArray_FromStringAndSize(r_ch_ptr, r_size);
+        }
+        bopy::object r_encoded_data = bopy::object(bopy::handle<>(r_encoded_data_ptr));
+
+        py_value.attr(value_attr_name) =
+            bopy::make_tuple(r_encoded_format, r_encoded_data);
+
+        if (self.get_written_dim_x() > 0)
+        {
+            bool is_write_type = self.get_written_dim_x() && (value_ptr->length() < 2);
+            if (is_write_type)
+            {
+                bopy::object w_encoded_format(r_encoded_format);
+                bopy::object w_encoded_data(r_encoded_data);
+                py_value.attr(w_value_attr_name) =
+                    bopy::make_tuple(w_encoded_format, w_encoded_data);
+            }
+            else 
+            {
+                Tango::DevEncoded& w_buffer = buffer[1];
+                bopy::str w_encoded_format(w_buffer.encoded_format);
+
+                Tango::DevVarCharArray& w_encoded_data_array = w_buffer.encoded_data;
+                char* w_ch_ptr = (char*) w_encoded_data_array.get_buffer();
+                PyObject* w_encoded_data_ptr = NULL;
+                    PyByteArray_FromStringAndSize(w_ch_ptr, w_encoded_data_array.length());
+                Py_ssize_t w_size = w_encoded_data_array.length();
+                if (read_only)
+                {
+                    w_encoded_data_ptr = PyBytes_FromStringAndSize(w_ch_ptr, w_size);
+                }
+                else
+                {
+                    w_encoded_data_ptr = PyByteArray_FromStringAndSize(w_ch_ptr, w_size);
+                }
+                bopy::object w_encoded_data = bopy::object(bopy::handle<>(w_encoded_data_ptr));
+
+                py_value.attr(value_attr_name) =
+                    bopy::make_tuple(w_encoded_format, w_encoded_data);
+            }
+        }
+        else
+        {
+            py_value.attr(w_value_attr_name) = bopy::object();
+        }
+    }
+
+    template<long tangoTypeConst> static inline void
+    _update_value_as_string(Tango::DeviceAttribute &self,
+                            bopy::object py_value)
+    {
+        typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+        typedef typename TANGO_const2arraytype(tangoTypeConst) TangoArrayType;
+
+        // Extract the actual data from Tango::DeviceAttribute (self)
+        TangoArrayType* value_ptr = 0;
+        EXTRACT_VALUE(self, value_ptr)
+        unique_pointer<TangoArrayType> guard_value_ptr(value_ptr);
+
+        if (value_ptr == 0)
+        {
+            py_value.attr(value_attr_name) = bopy::str();
+            py_value.attr(w_value_attr_name) = bopy::object();
+            return;
+        }
+
+        TangoScalarType* buffer = value_ptr->get_buffer();
+
+        const char* ch_ptr = reinterpret_cast<char *>(buffer);
+        size_t nb_bytes = value_ptr->length() * sizeof(TangoScalarType);
+
+        py_value.attr(value_attr_name) = bopy::str(ch_ptr, (size_t)nb_bytes);
+        py_value.attr(w_value_attr_name) = bopy::object();
+    }
+
+    template<> inline void
+    _update_value_as_string<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self,
+                                                bopy::object py_value)
+    {
+        Tango::DevVarEncodedArray* value_ptr;
+        EXTRACT_VALUE(self, value_ptr)
+        unique_pointer<Tango::DevVarEncodedArray> guard(value_ptr);
         
-        py_value.attr(value_attr_name) = boost::python::make_tuple(encoded_format, encoded_data);
-
-        if (self.get_written_dim_x() > 0) {
-            bool is_write_type = self.get_written_dim_x() && (value->length() < 2);
-            if (is_write_type) {
-                object w_encoded_format(encoded_format);
-                object w_encoded_data(encoded_data);
-                py_value.attr(w_value_attr_name) = boost::python::make_tuple(w_encoded_format, w_encoded_data);
-            } else {
-                str w_encoded_format(buffer[1].encoded_format);
-                str w_encoded_data((const char*)buffer[1].encoded_data.get_buffer(),
-                                   buffer[1].encoded_data.length());
-                py_value.attr(w_value_attr_name) = boost::python::make_tuple(w_encoded_format, w_encoded_data);
+        Tango::DevEncoded* buffer = value_ptr->get_buffer();
+
+        Tango::DevEncoded& r_buffer = buffer[0];
+        bopy::str r_encoded_format(r_buffer.encoded_format);
+
+        Tango::DevVarCharArray& r_encoded_data_array = r_buffer.encoded_data;
+        char* r_ch_ptr = (char*)r_encoded_data_array.get_buffer();
+        bopy::str r_encoded_data(r_ch_ptr, r_encoded_data_array.length());
+        
+        py_value.attr(value_attr_name) = 
+            bopy::make_tuple(r_encoded_format, r_encoded_data);
+
+        if (self.get_written_dim_x() > 0)
+        {
+            bool is_write_type = self.get_written_dim_x() && (value_ptr->length() < 2);
+            if (is_write_type)
+            {
+                bopy::object w_encoded_format(r_encoded_format);
+                bopy::object w_encoded_data(r_encoded_data);
+                py_value.attr(w_value_attr_name) =
+                    bopy::make_tuple(w_encoded_format, w_encoded_data);
             }
-        } else {
-            py_value.attr(w_value_attr_name) = object();
+            else
+            {
+                Tango::DevEncoded& w_buffer = buffer[1];
+                bopy::str w_encoded_format(w_buffer.encoded_format);
+
+                Tango::DevVarCharArray& w_encoded_data_array = w_buffer.encoded_data;
+                char* w_ch_ptr = (char*)w_encoded_data_array.get_buffer();
+                bopy::str w_encoded_data(w_ch_ptr, w_encoded_data_array.length());
+                py_value.attr(w_value_attr_name) = 
+                    bopy::make_tuple(w_encoded_format, w_encoded_data);
+            }
+        }
+        else
+        {
+            py_value.attr(w_value_attr_name) = bopy::object();
         }
     }
-    
-    template<long tangoTypeConst>
-    static inline void _update_scalar_values(Tango::DeviceAttribute &self, object py_value)
+
+    template<long tangoTypeConst> static inline void
+    _update_scalar_values(Tango::DeviceAttribute &self, bopy::object py_value)
     {
         typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
         
-        if (self.get_written_dim_x() > 0) {
+        if (self.get_written_dim_x() > 0)
+        {
             std::vector<TangoScalarType> val;
             self.extract_read(val);
             // In the following lines, the cast is absolutely necessary because
             // vector<TangoScalarType> may not be a vector<TangoScalarType> at
             // compile time. For example, for vector<DevBoolean>, the compiler
             // may create a std::_Bit_reference type.
-            py_value.attr(value_attr_name) = object((TangoScalarType)val[0]);
+            py_value.attr(value_attr_name) = bopy::object((TangoScalarType)val[0]);
             self.extract_set(val);
-            py_value.attr(w_value_attr_name) = object((TangoScalarType)val[0]);
-        } else {
+            py_value.attr(w_value_attr_name) = bopy::object((TangoScalarType)val[0]);
+        }
+        else
+        {
             TangoScalarType rvalue;
-            self >> rvalue;
-            py_value.attr(value_attr_name) = object(rvalue);
-            py_value.attr(w_value_attr_name) = object();
+            EXTRACT_VALUE(self, rvalue)
+            py_value.attr(value_attr_name) = bopy::object(rvalue);
+            py_value.attr(w_value_attr_name) = bopy::object();
         }
     }
 
-    template<>
-    inline void _update_scalar_values<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self, object py_value)
+    template<> inline void 
+    _update_scalar_values<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self,
+                                              bopy::object py_value)
     {
-        Tango::DevVarEncodedArray* value;
-        self >> value;
-        std::auto_ptr<Tango::DevVarEncodedArray> guard_value(value);
-        
-        Tango::DevEncoded* buffer = value->get_buffer();
-        
-        boost::python::str r_encoded_format(buffer[0].encoded_format);
-        
-        Tango::DevVarCharArray &encReadBuffer = buffer[0].encoded_data;
-        Py_ssize_t size = encReadBuffer.length();
-        
-        char *rawReadBuffer = (char *)encReadBuffer.get_buffer();
-        PyObject *readArray = PyString_FromStringAndSize(rawReadBuffer, size);
-
-        object r_encoded_data = object(handle<>(readArray));
-        
-        py_value.attr(value_attr_name) = boost::python::make_tuple(r_encoded_format, r_encoded_data);
-
-        if (self.get_written_dim_x() > 0) {
-            bool is_write_type = self.get_written_dim_x() && (value->length() < 2);
-            if (is_write_type) {
-                object w_encoded_format(r_encoded_format);
-                object w_encoded_data(r_encoded_data);
-                py_value.attr(w_value_attr_name) = boost::python::make_tuple(w_encoded_format, w_encoded_data);
-            } else {
-                str w_encoded_format(buffer[1].encoded_format);
-                
-                Tango::DevVarCharArray &encWriteBuffer = buffer[1].encoded_data;
-                int size = encWriteBuffer.length();
-                CORBA::Octet *rawWriteBuffer = encWriteBuffer.get_buffer(1);
-                
-                PyObject *writeArray = PyBuffer_FromReadWriteMemory(rawWriteBuffer, size);
-                
-                object w_encoded_data = object(handle<>(writeArray));
-                
-                py_value.attr(w_value_attr_name) = boost::python::make_tuple(w_encoded_format, w_encoded_data);
-            }
-        } else {
-            py_value.attr(w_value_attr_name) = object();
-        }
+        _update_value_as_string<Tango::DEV_ENCODED>(self, py_value);
     }
 
-    template<>
-    inline void _update_scalar_values<Tango::DEV_STRING>(Tango::DeviceAttribute &self, object py_value)
+    template<> inline void
+    _update_scalar_values<Tango::DEV_STRING>(Tango::DeviceAttribute &self,
+                                             bopy::object py_value)
     {
-        if (self.get_written_dim_x() > 0) {
-            std::vector<std::string> val;
-            self.extract_read(val);
-            py_value.attr(value_attr_name) = object(val[0]);
-            self.extract_set(val);
-            py_value.attr(w_value_attr_name) = object(val[0]);
-        } else {
+        if (self.get_written_dim_x() > 0)
+        {
+            std::vector<std::string> r_val, w_val;
+            self.extract_read(r_val);
+            py_value.attr(value_attr_name) = object(r_val[0]);
+            self.extract_set(w_val);
+            py_value.attr(w_value_attr_name) = object(w_val[0]);
+        }
+        else
+        {
             std::string rvalue;
-            self >> rvalue;
+            EXTRACT_VALUE(self, rvalue)
             py_value.attr(value_attr_name) = object(rvalue);
             py_value.attr(w_value_attr_name) = object();
         }
     }
 
-    template<long tangoTypeConst>
-    static inline void _update_array_values_as_lists(Tango::DeviceAttribute &self, bool isImage, object py_value)
+    template<long tangoTypeConst> static inline void
+    _update_array_values_as_lists(Tango::DeviceAttribute &self, bool isImage,
+                                  bopy::object py_value)
     {
         typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
         typedef typename TANGO_const2arraytype(tangoTypeConst) TangoArrayType;
 
         // Extract the actual data from Tango::DeviceAttribute (self)
         TangoArrayType* value_ptr = 0;
-        try {
-            self >> value_ptr;
-        } catch (Tango::DevFailed &e ) {
-            if (strcmp(e.errors[0].reason.in(),"API_EmptyDeviceAttribute") != 0)
-                throw;
-        }
-        std::auto_ptr<TangoArrayType> guard_value_ptr(value_ptr);
+        EXTRACT_VALUE(self, value_ptr)
+        unique_pointer<TangoArrayType> guard_value_ptr(value_ptr);
 
         if (value_ptr == 0) {
             // Empty device attribute
-            py_value.attr(value_attr_name) = boost::python::list();
+            py_value.attr(value_attr_name) = bopy::list();
             py_value.attr(w_value_attr_name) = object();
             return;
         }
@@ -272,14 +377,14 @@ namespace PyDeviceAttribute {
                 py_value.attr(w_value_attr_name) = py_value.attr(value_attr_name);
                 continue;
             }
-            boost::python::list result;
+            bopy::list result;
             
             if (isImage) {
                 const int dim_x = it? self.get_dim_x() : self.get_written_dim_x();
                 const int dim_y = it? self.get_dim_y() : self.get_written_dim_y();
                 
                 for (int y=0; y < dim_y; ++y) {
-                    boost::python::list row;
+                    bopy::list row;
                     for (int x=0; x < dim_x; ++x)
                         row.append(python_tangocpp<tangoTypeConst>::to_python(buffer[offset + x + y*dim_x]));
                     result.append(row);
@@ -295,67 +400,21 @@ namespace PyDeviceAttribute {
         }
     }
 
-    template<long tangoTypeConst>
-    static inline void _update_array_values_as_pytango3(Tango::DeviceAttribute &self, bool isImage, object py_value)
+    template<long tangoTypeConst> static void
+    _update_array_values_as_tuples(Tango::DeviceAttribute &self, bool isImage,
+                                   bopy::object py_value)
     {
         typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
         typedef typename TANGO_const2arraytype(tangoTypeConst) TangoArrayType;
 
         // Extract the actual data from Tango::DeviceAttribute (self)
         TangoArrayType* value_ptr = 0;
-        try {
-            self >> value_ptr;
-        } catch (Tango::DevFailed &e ) {
-            if (strcmp(e.errors[0].reason.in(),"API_EmptyDeviceAttribute") != 0)
-                throw;
-        }
-        std::auto_ptr<TangoArrayType> guard_value_ptr(value_ptr);
+        EXTRACT_VALUE(self, value_ptr)
+        unique_pointer<TangoArrayType> guard_value_ptr(value_ptr);
 
         if (value_ptr == 0) {
             // Empty device attribute
-            py_value.attr(value_attr_name) = boost::python::list();
-            py_value.attr(w_value_attr_name) = object();
-            return;
-        }
-
-        TangoScalarType* buffer = value_ptr->get_buffer();
-
-        long sz = value_ptr->length();
-        boost::python::list res;
-        for (long x =0; x<sz; ++x) {
-            res.append(python_tangocpp<tangoTypeConst>::to_python(buffer[x]));
-        }
-
-        py_value.attr(value_attr_name) = res;
-        py_value.attr(w_value_attr_name) = object();
-    }
-
-    template<>
-    inline void _update_array_values_as_pytango3<Tango::DEV_ENCODED>(Tango::DeviceAttribute &self, bool isImage, object py_value)
-    {
-        /// @todo DevEncoded didn't even exist in PyTango3...
-        _update_array_values_as_tuples<Tango::DEV_ENCODED>(self, isImage, py_value);
-    }
-
-    template<long tangoTypeConst>
-    void _update_array_values_as_tuples(Tango::DeviceAttribute &self, bool isImage, object py_value)
-    {
-        typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
-        typedef typename TANGO_const2arraytype(tangoTypeConst) TangoArrayType;
-
-        // Extract the actual data from Tango::DeviceAttribute (self)
-        TangoArrayType* value_ptr = 0;
-        try {
-            self >> value_ptr;
-        } catch (Tango::DevFailed &e ) {
-            if (strcmp(e.errors[0].reason.in(),"API_EmptyDeviceAttribute") != 0)
-                throw;
-        }
-        std::auto_ptr<TangoArrayType> guard_value_ptr(value_ptr);
-
-        if (value_ptr == 0) {
-            // Empty device attribute
-            py_value.attr(value_attr_name) = boost::python::tuple();
+            py_value.attr(value_attr_name) = bopy::tuple();
             py_value.attr(w_value_attr_name) = object();
             return;
         }
@@ -389,13 +448,13 @@ namespace PyDeviceAttribute {
 
                 PyObject * result = PyTuple_New(dim_y);
                 if (!result)
-                    boost::python::throw_error_already_set();
+                    bopy::throw_error_already_set();
                 result_guard = object(handle<>(result));
 
                 for (int y=0; y < dim_y; ++y) {
                     PyObject * row = PyTuple_New(dim_x);
                     if (!row)
-                        boost::python::throw_error_already_set();
+                        bopy::throw_error_already_set();
                     object row_guard = object(handle<>(row));
                     for (int x=0; x < dim_x; ++x) {
                         object el = python_tangocpp<tangoTypeConst>::to_python(buffer[offset + x + y*dim_x]);
@@ -411,7 +470,7 @@ namespace PyDeviceAttribute {
 
                 PyObject * result = PyTuple_New(dim_x);
                 if (!result)
-                    boost::python::throw_error_already_set();
+                    bopy::throw_error_already_set();
                 result_guard = object(handle<>(result));
 
                 for (int x=0; x < dim_x; ++x) {
@@ -425,13 +484,16 @@ namespace PyDeviceAttribute {
         }
     }
 
-    void update_values(Tango::DeviceAttribute &self, object& py_value, PyTango::ExtractAs extract_as/*=ExtractAsNumpy*/)
+    void
+    update_values(Tango::DeviceAttribute &self, bopy::object& py_value,
+                  PyTango::ExtractAs extract_as/*=ExtractAsNumpy*/)
     {
         // We do not want is_empty to launch an exception!!
         self.reset_exceptions(Tango::DeviceAttribute::isempty_flag);
+        
         // self.get_type() already does self.is_empty()
         const int data_type = self.get_type();
-        const bool is_empty = data_type < 0; /*self.is_empty()*/
+        const bool is_empty = data_type < 0;
         const bool has_failed = self.has_failed();
         Tango::AttrDataFormat data_format = self.get_data_format();
 
@@ -449,23 +511,40 @@ namespace PyDeviceAttribute {
         bool is_image = false;
         switch (data_format) {
             case Tango::SCALAR:
-                switch (extract_as)
+                if (data_type == Tango::DEV_ENCODED)
                 {
-                    default:
-                    case PyTango::ExtractAsNumpy:
-                    case PyTango::ExtractAsTuple:
-                    case PyTango::ExtractAsList:
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_scalar_values, self, py_value);
-                        break;
-                    case PyTango::ExtractAsString:
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_value_as_string, self, py_value);
-                        break;
-                    case PyTango::ExtractAsPyTango3:
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_scalar_values, self, py_value);
-                        py_value.attr("w_scalar_value") = py_value.attr(w_value_attr_name);
-                        break;
-                    case PyTango::ExtractAsNothing:
-                        break;
+                    switch (extract_as)
+                    {
+                        default:
+                        case PyTango::ExtractAsNumpy:
+                        case PyTango::ExtractAsTuple:
+                        case PyTango::ExtractAsList:
+                            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
+                                _update_scalar_values, self, py_value);
+                            break;
+                        case PyTango::ExtractAsBytes:
+                            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
+                                _update_value_as_bin, self, py_value, true);
+                            break;
+                        case PyTango::ExtractAsByteArray:
+                            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
+                                _update_value_as_bin, self, py_value, false);
+                            break;
+                        case PyTango::ExtractAsString:
+                            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
+                                _update_value_as_string, self, py_value);
+                            break;
+                        case PyTango::ExtractAsNothing:
+                            break;
+                    }
+                }
+                else
+                {
+                    if (extract_as != PyTango::ExtractAsNothing)
+                    {
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
+                            _update_scalar_values, self, py_value);
+                    }
                 }
                 break;
             case Tango::IMAGE:
@@ -476,25 +555,29 @@ namespace PyDeviceAttribute {
                     default:
                     case PyTango::ExtractAsNumpy:
 #                   ifndef DISABLE_PYTANGO_NUMPY
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_array_values,
-                                           self, is_image, py_value);
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
+                            _update_array_values, self, is_image, py_value);
                         break;
 #                   endif
                     case PyTango::ExtractAsTuple:
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_array_values_as_tuples,
-                                           self, is_image, py_value);
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
+                            _update_array_values_as_tuples, self, is_image, py_value);
                         break;
                     case PyTango::ExtractAsList:
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_array_values_as_lists,
-                                           self, is_image, py_value);
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
+                            _update_array_values_as_lists, self, is_image, py_value);
                         break;
-                    case PyTango::ExtractAsString:
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_value_as_string,
-                                           self, py_value);
+                    case PyTango::ExtractAsBytes:
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
+                            _update_value_as_bin, self, py_value, true);
                         break;
-                    case PyTango::ExtractAsPyTango3:
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(data_type, _update_array_values_as_pytango3,
-                                           self, is_image, py_value);
+                    case PyTango::ExtractAsByteArray:
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
+                            _update_value_as_bin, self, py_value, false);
+                        break;
+                    case PyTango::ExtractAsString:
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(data_type,
+                            _update_value_as_string, self, py_value);
                         break;
                     case PyTango::ExtractAsNothing:
                         break;
@@ -507,8 +590,9 @@ namespace PyDeviceAttribute {
         }
     }
 
-    template<long tangoTypeConst>
-    static inline void _fill_list_attribute(Tango::DeviceAttribute & dev_attr, const bool isImage, const object & py_value)
+    template<long tangoTypeConst> static inline void
+    _fill_list_attribute(Tango::DeviceAttribute & dev_attr, const bool isImage,
+                         const bopy::object & py_value)
     {
         typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
         typedef typename TANGO_const2arraytype(tangoTypeConst) TangoArrayType;
@@ -527,7 +611,7 @@ namespace PyDeviceAttribute {
         }
 
         // -- Allocate memory
-        std::auto_ptr<TangoArrayType> value;
+        unique_pointer<TangoArrayType> value;
         TangoScalarType* buffer = TangoArrayType::allocbuf(nelems);
         try {
             value.reset(new TangoArrayType(nelems, nelems, buffer, true));
@@ -559,26 +643,31 @@ namespace PyDeviceAttribute {
         value.release(); // Do not delete value, it is handled by dev_attr now!
     }
 
-    template<>
-    inline void _fill_list_attribute<Tango::DEV_ENCODED>(Tango::DeviceAttribute & dev_attr, const bool isImage, const object & py_value)
+    template<> inline void
+    _fill_list_attribute<Tango::DEV_ENCODED>(Tango::DeviceAttribute & dev_attr,
+                                             const bool isImage,
+                                             const bopy::object & py_value)
     {
         /// @todo really? This is really not gonna happen?
         // Unsupported
         assert(false);
     }
 
-    static inline object undefined_attribute(Tango::DeviceAttribute* self)
+    static inline bopy::object
+    undefined_attribute(Tango::DeviceAttribute* self)
     {
         return object(); // None
     }
 
-    void reset_values(Tango::DeviceAttribute & self, int data_type, Tango::AttrDataFormat data_format, object py_value)
+    void
+    reset_values(Tango::DeviceAttribute & self, int data_type,
+                 Tango::AttrDataFormat data_format, bopy::object py_value)
     {
         bool isImage = false;
         switch(data_format)
         {
             case Tango::SCALAR:
-                TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE( data_type, _fill_scalar_attribute, self, py_value );
+                TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID( data_type, _fill_scalar_attribute, self, py_value );
                 break;
             case Tango::IMAGE:
                 isImage = true;
@@ -594,14 +683,14 @@ namespace PyDeviceAttribute {
                 // standard types and C++ are.
 #               ifdef DISABLE_PYTANGO_NUMPY
                 {
-                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE( data_type, _fill_list_attribute, self, isImage, py_value );
+                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID( data_type, _fill_list_attribute, self, isImage, py_value );
                 }
 #               else
                 {
                     if (PyArray_Check(py_value.ptr()))
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE( data_type, _fill_numpy_attribute, self, isImage, py_value );
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID( data_type, _fill_numpy_attribute, self, isImage, py_value );
                     else
-                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE( data_type, _fill_list_attribute, self, isImage, py_value );
+                        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID( data_type, _fill_list_attribute, self, isImage, py_value );
                     break;
                 }
 #               endif
@@ -610,13 +699,17 @@ namespace PyDeviceAttribute {
         }
     }
 
-    void reset(Tango::DeviceAttribute & self, const Tango::AttributeInfo &attr_info, object py_value)
+    void
+    reset(Tango::DeviceAttribute & self, const Tango::AttributeInfo &attr_info,
+          bopy::object py_value)
     {
         self.set_name(const_cast<std::string&>(attr_info.name));
         reset_values(self, attr_info.data_type, attr_info.data_format, py_value);
     }
 
-    void reset(Tango::DeviceAttribute & self, const std::string &attr_name, Tango::DeviceProxy &dev_proxy, object py_value)
+    void
+    reset(Tango::DeviceAttribute & self, const std::string &attr_name,
+          Tango::DeviceProxy &dev_proxy, bopy::object py_value)
     {
         Tango::AttributeInfoEx attr_info;
         {
@@ -661,5 +754,7 @@ void export_device_attribute()
             return_internal_reference<>())
         .def("get_err_stack", &Tango::DeviceAttribute::get_err_stack,
             return_value_policy<copy_const_reference>())
+        .def("set_w_dim_x", &Tango::DeviceAttribute::set_w_dim_x)
+        .def("set_w_dim_y", &Tango::DeviceAttribute::set_w_dim_y)
     ;
 }
diff --git a/src/device_attribute.h b/src/device_attribute.h
index 1f4ca41..f5757e1 100644
--- a/src/device_attribute.h
+++ b/src/device_attribute.h
@@ -38,7 +38,7 @@ namespace PyDeviceAttribute {
 
 /// @name Types
 /// @{
-    typedef std::auto_ptr<std::vector<Tango::DeviceAttribute> > AutoDevAttrVector;
+    typedef unique_pointer<std::vector<Tango::DeviceAttribute> > AutoDevAttrVector;
 /// @}
     
     template<long tangoTypeConst>
@@ -71,7 +71,7 @@ namespace PyDeviceAttribute {
             }
         }
         if (attr_names.size()) {
-            std::auto_ptr<Tango::AttributeInfoListEx> attr_infos;
+            unique_pointer<Tango::AttributeInfoListEx> attr_infos;
             {
                 AutoPythonAllowThreads guard;
                 p = first;
@@ -132,7 +132,7 @@ namespace PyDeviceAttribute {
     /// as we get a reference to auto_ptr -> the caller must use an auto_ptr,
     /// so the memory will finally be deleted.
     template<typename TDeviceAttribute>
-    boost::python::object convert_to_python(const std::auto_ptr<std::vector<TDeviceAttribute> >& dev_attr_vec, Tango::DeviceProxy & dev_proxy, PyTango::ExtractAs extract_as)
+    boost::python::object convert_to_python(const unique_pointer<std::vector<TDeviceAttribute> >& dev_attr_vec, Tango::DeviceProxy & dev_proxy, PyTango::ExtractAs extract_as)
     {
         update_data_format(dev_proxy, &(*dev_attr_vec)[0], dev_attr_vec->size());
 
diff --git a/src/device_attribute_config.cpp b/src/device_attribute_config.cpp
index a3fa257..9ad336c 100644
--- a/src/device_attribute_config.cpp
+++ b/src/device_attribute_config.cpp
@@ -29,7 +29,7 @@ using namespace boost::python;
 void export_device_attribute_config()
 {
     class_<Tango::DeviceAttributeConfig>("DeviceAttributeConfig")
-        .def(init<const Tango::AttributeInfoEx&>())
+        .def(init<const Tango::DeviceAttributeConfig&>())
         .def_readwrite("name", &Tango::DeviceAttributeConfig::name)
         .def_readwrite("writable", &Tango::DeviceAttributeConfig::writable)
         .def_readwrite("data_format", &Tango::DeviceAttributeConfig::data_format)
@@ -37,7 +37,9 @@ void export_device_attribute_config()
         .def_readwrite("max_dim_x", &Tango::DeviceAttributeConfig::max_dim_x)
         .def_readwrite("max_dim_y", &Tango::DeviceAttributeConfig::max_dim_y)
         .def_readwrite("description", &Tango::DeviceAttributeConfig::description)
-        .def_readwrite("label", &Tango::DeviceAttributeConfig::label)
+        //.def_readwrite("label", &Tango::DeviceAttributeConfig::label)
+        .add_property("label", make_getter(&Tango::DeviceAttributeConfig::label, return_value_policy<return_by_value>()),
+                               make_setter(&Tango::DeviceAttributeConfig::label, return_value_policy<return_by_value>()))
         .def_readwrite("unit", &Tango::DeviceAttributeConfig::unit)
         .def_readwrite("standard_unit", &Tango::DeviceAttributeConfig::standard_unit)
         .def_readwrite("display_unit", &Tango::DeviceAttributeConfig::display_unit)
diff --git a/src/device_attribute_numpy.hpp b/src/device_attribute_numpy.hpp
index 90eeb92..9dab76f 100644
--- a/src/device_attribute_numpy.hpp
+++ b/src/device_attribute_numpy.hpp
@@ -35,14 +35,24 @@ namespace PyDeviceAttribute {
     /// @param ptr_ The array object.
     /// @param type_ The type of the array objects. We need it to convert ptr_
     ///              to the proper type before deleting it. ex: Tango::DEV_SHORT.
-    static void _dev_var_x_array_deleter(void * ptr_, void *type_)
+#ifdef PYCAPSULE_OLD
+    template<long type>
+    static void _dev_var_x_array_deleter(void * ptr_)
     {
-        long type = reinterpret_cast<long>(type_);
-
-        TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(type,
+        TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_ID(type,
+            delete static_cast<TANGO_const2arraytype(tangoTypeConst)*>(ptr_);
+        );
+    }
+#else
+    template<long type>
+    static void _dev_var_x_array_deleter(PyObject* obj)
+    {
+        void * ptr_ = PyCapsule_GetPointer(obj, NULL);
+        TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_ID(type,
             delete static_cast<TANGO_const2arraytype(tangoTypeConst)*>(ptr_);
         );
     }
+#endif
 
     template<long tangoTypeConst>
     static inline void _update_array_values(Tango::DeviceAttribute &self, bool isImage, object py_value)
@@ -123,18 +133,18 @@ namespace PyDeviceAttribute {
         // the last copy of numpy.ndarray() disappears.
         // PyCObject is intended for that kind of things. It's seen as a
         // black box object from python. We assign him a function to be called
-        // when it is deleted -> the function deletes de data.
-        PyObject* guard = PyCObject_FromVoidPtrAndDesc(
+        // when it is deleted -> the function deletes the data.
+        PyObject* guard = PyCapsule_New(
                 static_cast<void*>(value_ptr),
-                reinterpret_cast<void*>(tangoTypeConst),
-                _dev_var_x_array_deleter);
+                NULL,
+                _dev_var_x_array_deleter<tangoTypeConst>);
         if (!guard ) {
             Py_XDECREF(array);
             Py_XDECREF(warray);
             delete value_ptr;
             throw_error_already_set();
         }
-
+        
         PyArray_BASE(array) = guard;
         py_value.attr(value_attr_name) = boost::python::object(boost::python::handle<>(array));
 
@@ -200,7 +210,7 @@ namespace PyDeviceAttribute {
             raise_(PyExc_TypeError, isImage? non_valid_image : non_valid_spectrum);
 
         // -- Allocate memory for the new data object
-        std::auto_ptr<TangoArrayType> value;
+        unique_pointer<TangoArrayType> value;
         TangoScalarType* buffer = TangoArrayType::allocbuf(nelems);
         try {
             value.reset(new TangoArrayType(nelems, nelems, buffer, true));
diff --git a/src/device_data.cpp b/src/device_data.cpp
index 9e4845c..000be4f 100644
--- a/src/device_data.cpp
+++ b/src/device_data.cpp
@@ -50,6 +50,21 @@ namespace PyDeviceData {
             self << val;
         }
         template <>
+        void insert_scalar<Tango::DEV_ENCODED>(Tango::DeviceData &self, object py_value)
+        {
+            object p0 = py_value[0];
+            object p1 = py_value[1];
+            const char* encoded_format = extract<const char *> (p0.ptr());
+            const char* encoded_data = extract<const char *> (p1.ptr());
+            
+            CORBA::ULong nb = boost::python::len(p1);
+            Tango::DevVarCharArray arr(nb, nb, (CORBA::Octet*)encoded_data, false);
+            Tango::DevEncoded val;
+            val.encoded_format = CORBA::string_dup(encoded_format);
+            val.encoded_data = arr;
+            self << val;
+        }
+        template <>
         void insert_scalar<Tango::DEV_VOID>(Tango::DeviceData &self, object py_value)
         {
             raise_(PyExc_TypeError, "Trying to insert a value in a DEV_VOID DeviceData!");
@@ -62,7 +77,7 @@ namespace PyDeviceData {
     /// @{
         template <long tangoArrayTypeConst>
         void insert_array(Tango::DeviceData &self, object py_value)
-        {            
+        {
             typedef typename TANGO_const2type(tangoArrayTypeConst) TangoArrayType;
 
             // self << val; -->> This ends up doing:
@@ -131,7 +146,6 @@ namespace PyDeviceData {
                     return to_py_numpy<tangoArrayTypeConst>(tmp_ptr, py_self);
 #                 endif
                 case PyTango::ExtractAsList:
-                case PyTango::ExtractAsPyTango3:
                     return to_py_list(tmp_ptr);
                 case PyTango::ExtractAsTuple:
                     return to_py_tuple(tmp_ptr);
@@ -148,7 +162,7 @@ namespace PyDeviceData {
     {
         Tango::DeviceData &self = boost::python::extract<Tango::DeviceData &>(py_self);
         
-        TANGO_DO_ON_DEVICE_DATA_TYPE(self.get_type(),
+        TANGO_DO_ON_DEVICE_DATA_TYPE_ID(self.get_type(),
             return extract_scalar<tangoTypeConst>(self);
         ,
             return extract_array<tangoTypeConst>(self, py_self, extract_as);
@@ -158,7 +172,7 @@ namespace PyDeviceData {
 
     void insert(Tango::DeviceData &self, long data_type, object py_value)
     {
-        TANGO_DO_ON_DEVICE_DATA_TYPE(data_type,
+        TANGO_DO_ON_DEVICE_DATA_TYPE_ID(data_type,
             insert_scalar<tangoTypeConst>(self, py_value);
         , 
             insert_array<tangoTypeConst>(self, py_value);
diff --git a/src/device_proxy.cpp b/src/device_proxy.cpp
index 1c7dd69..dfc6e8d 100644
--- a/src/device_proxy.cpp
+++ b/src/device_proxy.cpp
@@ -27,8 +27,6 @@
 #include "defs.h"
 #include "pytgutils.h"
 
-using namespace boost::python;
-
 extern const char *param_must_be_seq;
 extern const char *unreachable_code;
 extern const char *non_string_seq;
@@ -38,12 +36,13 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(unlock_overloads, Tango::DeviceProxy::unl
 
 namespace PyDeviceProxy
 {
-    struct PickleSuite : pickle_suite
+    struct PickleSuite : bopy::pickle_suite
     {
-        static tuple getinitargs(Tango::DeviceProxy& self)
+        static bopy::tuple getinitargs(Tango::DeviceProxy& self)
         {
-            std::string ret = self.get_db_host() + ":" + self.get_db_port() + "/" + self.dev_name();
-            return make_tuple(ret);
+            std::string ret = self.get_db_host() + ":" + self.get_db_port() +
+                              "/" + self.dev_name();
+            return bopy::make_tuple(ret);
         }
     };
     
@@ -65,22 +64,23 @@ namespace PyDeviceProxy
         return self.ping();
     }
 
-    static inline void pylist_to_devattrs(Tango::DeviceProxy& self, object &py_list, std::vector<Tango::DeviceAttribute> &dev_attrs)
+    static inline void pylist_to_devattrs(Tango::DeviceProxy& self,
+        bopy::object &py_list, std::vector<Tango::DeviceAttribute> &dev_attrs)
     {
         std::vector<std::string> attr_names;
-        std::vector<object> py_values;
+        std::vector<bopy::object> py_values;
         long size = len(py_list);
 
         // Fill attr_names and py_values
         for (long n = 0; n < size; ++n) {
-            object tup = py_list[n];
-            std::string attr_name = extract<std::string>(tup[0]);
+            bopy::object tup = py_list[n];
+            std::string attr_name = bopy::extract<std::string>(tup[0]);
             attr_names.push_back(attr_name);
             py_values.push_back(tup[1]);
         }
 
         // Get attr_info for all the attr_names
-        std::auto_ptr<Tango::AttributeInfoListEx> attr_infos;
+        unique_pointer<Tango::AttributeInfoListEx> attr_infos;
         {
             AutoPythonAllowThreads guard;
             attr_infos.reset(self.get_attribute_config_ex(attr_names));
@@ -93,7 +93,7 @@ namespace PyDeviceProxy
         }
     }
 
-    static inline object read_attribute(Tango::DeviceProxy& self, const string & attr_name, PyTango::ExtractAs extract_as)
+    static inline bopy::object read_attribute(Tango::DeviceProxy& self, const string & attr_name, PyTango::ExtractAs extract_as)
     {
         // Even if there's an exception in convert_to_python, the
         // DeviceAttribute will be deleted there, so we don't need to worry.
@@ -106,7 +106,7 @@ namespace PyDeviceProxy
         return PyDeviceAttribute::convert_to_python(dev_attr, self, extract_as);
     }
 
-    static inline object read_attributes(Tango::DeviceProxy& self, object py_attr_names, PyTango::ExtractAs extract_as)
+    static inline bopy::object read_attributes(Tango::DeviceProxy& self, bopy::object py_attr_names, PyTango::ExtractAs extract_as)
     {
         CSequenceFromPython<StdStringVector> attr_names(py_attr_names);
 
@@ -119,7 +119,7 @@ namespace PyDeviceProxy
         return PyDeviceAttribute::convert_to_python(dev_attr_vec, self, extract_as);
     }
 
-    static inline void write_attribute(Tango::DeviceProxy& self, const Tango::AttributeInfo & attr_info, object py_value)
+    static inline void write_attribute(Tango::DeviceProxy& self, const Tango::AttributeInfo & attr_info, bopy::object py_value)
     {
         Tango::DeviceAttribute da;
         PyDeviceAttribute::reset(da, attr_info, py_value);
@@ -127,7 +127,7 @@ namespace PyDeviceProxy
         self.write_attribute(da);
     }
 
-    static inline void write_attribute(Tango::DeviceProxy& self, const string & attr_name, object py_value)
+    static inline void write_attribute(Tango::DeviceProxy& self, const string & attr_name, bopy::object py_value)
     {
         Tango::DeviceAttribute dev_attr;
         PyDeviceAttribute::reset(dev_attr, attr_name, self, py_value);
@@ -137,7 +137,7 @@ namespace PyDeviceProxy
         }
     }
 
-    static inline void write_attributes(Tango::DeviceProxy& self, object py_list)
+    static inline void write_attributes(Tango::DeviceProxy& self, bopy::object py_list)
     {
         std::vector<Tango::DeviceAttribute> dev_attrs;
         pylist_to_devattrs(self, py_list, dev_attrs);
@@ -146,10 +146,10 @@ namespace PyDeviceProxy
         self.write_attributes(dev_attrs);
     }
 
-    static inline object write_read_attribute(Tango::DeviceProxy& self, const string & attr_name, object py_value, PyTango::ExtractAs extract_as)
+    static inline bopy::object write_read_attribute(Tango::DeviceProxy& self, const string & attr_name, bopy::object py_value, PyTango::ExtractAs extract_as)
     {
         Tango::DeviceAttribute w_dev_attr;
-        std::auto_ptr<Tango::DeviceAttribute> r_dev_attr(0);
+        unique_pointer<Tango::DeviceAttribute> r_dev_attr;
 
         // Prepare dev_attr structure
         PyDeviceAttribute::reset(w_dev_attr, attr_name, self, py_value);
@@ -164,11 +164,11 @@ namespace PyDeviceProxy
         return PyDeviceAttribute::convert_to_python(r_dev_attr.release(), self, extract_as);
     }
 
-    static inline object
-            command_history(Tango::DeviceProxy& self, const std::string & cmd_name, int depth)
+    static inline bopy::object
+    command_history(Tango::DeviceProxy& self, const std::string& cmd_name, int depth)
     {
-        vector<Tango::DeviceDataHistory>* device_data_hist = NULL;
-        boost::python::list ret;
+        std::vector<Tango::DeviceDataHistory>* device_data_hist = NULL;
+        bopy::list ret;
         {
             AutoPythonAllowThreads guard;
             device_data_hist =
@@ -184,10 +184,10 @@ namespace PyDeviceProxy
         return ret;
     }
 
-    static inline object
+    static inline bopy::object
             attribute_history(Tango::DeviceProxy& self, const std::string & attr_name, int depth, PyTango::ExtractAs extract_as)
     {
-        std::auto_ptr< vector<Tango::DeviceAttributeHistory> > att_hist;
+        unique_pointer< vector<Tango::DeviceAttributeHistory> > att_hist;
         {
             AutoPythonAllowThreads guard;
             att_hist.reset(self.attribute_history(const_cast<std::string&>(attr_name), depth));
@@ -196,7 +196,7 @@ namespace PyDeviceProxy
     }
 
 
-    static inline long read_attributes_asynch(Tango::DeviceProxy& self, object py_attr_names)
+    static inline long read_attributes_asynch(Tango::DeviceProxy& self, bopy::object py_attr_names)
     {
         CSequenceFromPython<StdStringVector> attr_names(py_attr_names);
 
@@ -206,7 +206,7 @@ namespace PyDeviceProxy
 
 
 
-    static inline object read_attributes_reply(Tango::DeviceProxy& self, long id, PyTango::ExtractAs extract_as)
+    static inline bopy::object read_attributes_reply(Tango::DeviceProxy& self, long id, PyTango::ExtractAs extract_as)
     {
         PyDeviceAttribute::AutoDevAttrVector dev_attr_vec;
         {
@@ -216,7 +216,7 @@ namespace PyDeviceProxy
         return PyDeviceAttribute::convert_to_python(dev_attr_vec, self, extract_as);
     }
 
-    static inline object read_attributes_reply(Tango::DeviceProxy& self, long id, long timeout, PyTango::ExtractAs extract_as)
+    static inline bopy::object read_attributes_reply(Tango::DeviceProxy& self, long id, long timeout, PyTango::ExtractAs extract_as)
     {
         PyDeviceAttribute::AutoDevAttrVector dev_attr_vec;
         {
@@ -226,7 +226,7 @@ namespace PyDeviceProxy
         return PyDeviceAttribute::convert_to_python(dev_attr_vec, self, extract_as);
     }
 
-    static inline long write_attributes_asynch(Tango::DeviceProxy& self, object py_list)
+    static inline long write_attributes_asynch(Tango::DeviceProxy& self, bopy::object py_list)
     {
         std::vector<Tango::DeviceAttribute> dev_attrs;
         pylist_to_devattrs(self, py_list, dev_attrs);
@@ -247,12 +247,12 @@ namespace PyDeviceProxy
         self.write_attributes_reply(id);
     }
 
-    static inline void read_attributes_asynch(object py_self, object py_attr_names, object py_cb, PyTango::ExtractAs extract_as)
+    static inline void read_attributes_asynch(bopy::object py_self, bopy::object py_attr_names, bopy::object py_cb, PyTango::ExtractAs extract_as)
     {
-        Tango::DeviceProxy* self = extract<Tango::DeviceProxy*>(py_self);
+        Tango::DeviceProxy* self = bopy::extract<Tango::DeviceProxy*>(py_self);
         CSequenceFromPython<StdStringVector> attr_names(py_attr_names);
 
-        PyCallBackAutoDie* cb = extract<PyCallBackAutoDie*>(py_cb);
+        PyCallBackAutoDie* cb = bopy::extract<PyCallBackAutoDie*>(py_cb);
         cb->set_autokill_references(py_cb, py_self);
         cb->set_extract_as(extract_as);
 
@@ -265,13 +265,13 @@ namespace PyDeviceProxy
         }
     }
 
-    static inline void write_attributes_asynch(object py_self, object py_list, object py_cb)
+    static inline void write_attributes_asynch(bopy::object py_self, bopy::object py_list, bopy::object py_cb)
     {
-        Tango::DeviceProxy* self = extract<Tango::DeviceProxy*>(py_self);
+        Tango::DeviceProxy* self = bopy::extract<Tango::DeviceProxy*>(py_self);
         std::vector<Tango::DeviceAttribute> dev_attrs;
         pylist_to_devattrs(*self, py_list, dev_attrs);
 
-        PyCallBackAutoDie* cb = extract<PyCallBackAutoDie*>(py_cb);
+        PyCallBackAutoDie* cb = bopy::extract<PyCallBackAutoDie*>(py_cb);
         cb->set_autokill_references(py_cb, py_self);
 
         try {
@@ -284,21 +284,21 @@ namespace PyDeviceProxy
     }
 
     static int subscribe_event(
-            object py_self,
+            bopy::object py_self,
             const string &attr_name,
             Tango::EventType event,
-            object py_cb_or_queuesize,
-            object &py_filters,
+            bopy::object py_cb_or_queuesize,
+            bopy::object &py_filters,
             bool stateless,
             PyTango::ExtractAs extract_as )
     {
-        Tango::DeviceProxy& self = extract<Tango::DeviceProxy&>(py_self);
+        Tango::DeviceProxy& self = bopy::extract<Tango::DeviceProxy&>(py_self);
         CSequenceFromPython<StdStringVector> filters(py_filters);
 
         PyCallBackPushEvent* cb = 0;
         int event_queue_size = 0;
-        if (extract<PyCallBackPushEvent&>(py_cb_or_queuesize).check()) {
-            cb = extract<PyCallBackPushEvent*>(py_cb_or_queuesize);
+        if (bopy::extract<PyCallBackPushEvent&>(py_cb_or_queuesize).check()) {
+            cb = bopy::extract<PyCallBackPushEvent*>(py_cb_or_queuesize);
 
             cb->set_device(py_self);
             cb->set_extract_as(extract_as);
@@ -306,9 +306,10 @@ namespace PyDeviceProxy
             AutoPythonAllowThreads guard;
             return self.subscribe_event(attr_name, event, cb, *filters, stateless);
         } else {
-            event_queue_size = extract<int>(py_cb_or_queuesize);
+            event_queue_size = bopy::extract<int>(py_cb_or_queuesize);
             AutoPythonAllowThreads guard;
-            return self.subscribe_event(attr_name, event, event_queue_size, *filters, stateless);
+            return self.subscribe_event(attr_name, event, event_queue_size,
+                                        *filters, stateless);
         }
     }
 
@@ -321,26 +322,26 @@ namespace PyDeviceProxy
     }
 
     template<typename ED, typename EDList>
-    static object
-    get_events__aux(object py_self, int event_id, PyTango::ExtractAs extract_as=PyTango::ExtractAsNumpy)
+    static bopy::object
+    get_events__aux(bopy::object py_self, int event_id,
+                    PyTango::ExtractAs extract_as=PyTango::ExtractAsNumpy)
     {
-        Tango::DeviceProxy &self = extract<Tango::DeviceProxy&>(py_self);
+        Tango::DeviceProxy &self = bopy::extract<Tango::DeviceProxy&>(py_self);
 
         EDList event_list;
         self.get_events(event_id, event_list);
 
-        boost::python::list r;
+        bopy::list r;
 
         for (size_t i=0; i < event_list.size(); ++i) {
             ED* event_data = event_list[i];
 
-            object py_ev(handle<>(
-                            to_python_indirect<
-                                ED*,
-                                detail::make_owning_holder>()(event_data)));
+            bopy::object py_ev(bopy::handle<>(
+                bopy::to_python_indirect<
+                    ED*, bopy::detail::make_owning_holder>()(event_data)));
 
             // EventDataList deletes EventData's on destructor, so once
-            // we are handling it somewhere else (as an object) we must
+            // we are handling it somewhere else (as an bopy::object) we must
             // unset the reference
             event_list[i] = 0;
 
@@ -352,9 +353,10 @@ namespace PyDeviceProxy
     }
 
     static void
-    get_events__callback(object py_self, int event_id, PyCallBackPushEvent *cb, PyTango::ExtractAs extract_as)
+    get_events__callback(bopy::object py_self, int event_id,
+                         PyCallBackPushEvent *cb, PyTango::ExtractAs extract_as)
     {
-        Tango::DeviceProxy& self = extract<Tango::DeviceProxy&>(py_self);
+        Tango::DeviceProxy& self = bopy::extract<Tango::DeviceProxy&>(py_self);
 
         cb->set_device(py_self);
         cb->set_extract_as(extract_as);
@@ -362,22 +364,22 @@ namespace PyDeviceProxy
         self.get_events(event_id, cb);
     }
 
-    static object
-    get_events__attr_conf(object py_self, int event_id)
+    static bopy::object
+    get_events__attr_conf(bopy::object py_self, int event_id)
     {
         return get_events__aux<Tango::AttrConfEventData, Tango::AttrConfEventDataList>
                                                 (py_self, event_id);
     }
 
-    static object
-    get_events__data(object py_self, int event_id, PyTango::ExtractAs extract_as)
+    static bopy::object
+    get_events__data(bopy::object py_self, int event_id, PyTango::ExtractAs extract_as)
     {
         return get_events__aux<Tango::EventData, Tango::EventDataList>
                                                 (py_self, event_id, extract_as);
     }
 
-    static object
-    get_events__data_ready(object py_self, int event_id)
+    static bopy::object
+    get_events__data_ready(bopy::object py_self, int event_id)
     {
         return get_events__aux<Tango::DataReadyEventData, Tango::DataReadyEventDataList>
                                                 (py_self, event_id);
@@ -396,15 +398,14 @@ void export_device_proxy()
     void (Tango::DeviceProxy::*delete_property_)(std::string &) =
         &Tango::DeviceProxy::delete_property;
 
-    class_<Tango::DeviceProxy, bases<Tango::Connection> > DeviceProxy(
-        "DeviceProxy",
-        init<>())
+    bopy::class_<Tango::DeviceProxy, bopy::bases<Tango::Connection> >
+        DeviceProxy("DeviceProxy", bopy::init<>())
     ;
 
     DeviceProxy
-        .def(init<const char *>())
-        .def(init<const char *, bool>())
-        .def(init<const Tango::DeviceProxy &>())
+        .def(bopy::init<const char *>())
+        .def(bopy::init<const char *, bool>())
+        .def(bopy::init<const Tango::DeviceProxy &>())
 
         //
         // Pickle
@@ -418,10 +419,10 @@ void export_device_proxy()
         
         .def("info", &Tango::DeviceProxy::info,
             ( arg_("self") ),
-            return_internal_reference<1>() )
+            bopy::return_internal_reference<1>() )
 
         .def("get_device_db", &Tango::DeviceProxy::get_device_db,
-            return_value_policy<reference_existing_object>())
+            bopy::return_value_policy<bopy::reference_existing_object>())
 
         .def("status", &PyDeviceProxy::status,
             ( arg_("self") ) )
@@ -447,7 +448,7 @@ void export_device_proxy()
 
         .def("black_box", &Tango::DeviceProxy::black_box,
             ( arg_("self"), arg_("n") ),
-            return_value_policy<manage_new_object>() )
+            bopy::return_value_policy<bopy::manage_new_object>() )
 
         //
         // device methods
@@ -458,7 +459,7 @@ void export_device_proxy()
 
         .def("command_list_query", &Tango::DeviceProxy::command_list_query,
             ( arg_("self") ),
-            return_value_policy<manage_new_object>() )
+            bopy::return_value_policy<bopy::manage_new_object>() )
 
         .def("import_info", &Tango::DeviceProxy::import_info,
             ( arg_("self") ) )
@@ -505,13 +506,13 @@ void export_device_proxy()
 
         .def("get_attribute_list", &Tango::DeviceProxy::get_attribute_list,
             ( arg_("self") ),
-            return_value_policy<manage_new_object>() )
+            bopy::return_value_policy<bopy::manage_new_object>() )
 
         .def("_get_attribute_config",
             (Tango::AttributeInfoList* (Tango::DeviceProxy::*)(StdStringVector &))
             &Tango::DeviceProxy::get_attribute_config,
             ( arg_("self"), arg_("attr_names") ),
-            return_value_policy<manage_new_object>() )
+            bopy::return_value_policy<bopy::manage_new_object>() )
 
         .def("_get_attribute_config",
             (Tango::AttributeInfoEx (Tango::DeviceProxy::*)(const std::string&))
@@ -521,19 +522,19 @@ void export_device_proxy()
         .def("_get_attribute_config_ex",
             &Tango::DeviceProxy::get_attribute_config_ex,
             ( arg_("self"), arg_("attr_names") ),
-            return_value_policy<manage_new_object>() )
+            bopy::return_value_policy<bopy::manage_new_object>() )
 
         .def("attribute_query", &Tango::DeviceProxy::attribute_query,
             ( arg_("self"), arg_("attr_name") ) )
 
         .def("attribute_list_query", &Tango::DeviceProxy::attribute_list_query,
             ( arg_("self") ),
-            return_value_policy<manage_new_object>() )
+            bopy::return_value_policy<bopy::manage_new_object>() )
 
         .def("attribute_list_query_ex",
             &Tango::DeviceProxy::attribute_list_query_ex,
             ( arg_("self") ),
-            return_value_policy<manage_new_object>() )
+            bopy::return_value_policy<bopy::manage_new_object>() )
 
         .def("_set_attribute_config",
             (void (Tango::DeviceProxy::*)(Tango::AttributeInfoList &))
@@ -554,12 +555,12 @@ void export_device_proxy()
             ( arg_("self"), arg_("attr_names"), arg_("extract_as")=PyTango::ExtractAsNumpy ) )
 
         .def("write_attribute",
-            (void (*)(Tango::DeviceProxy&, const string &, object ))
+            (void (*)(Tango::DeviceProxy&, const string &, bopy::object ))
             &PyDeviceProxy::write_attribute,
             ( arg_("self"), arg_("attr_name"), arg_("value") ) )
 
         .def("write_attribute",
-            (void (*)(Tango::DeviceProxy&, const Tango::AttributeInfo &, object ))
+            (void (*)(Tango::DeviceProxy&, const Tango::AttributeInfo &, bopy::object ))
             &PyDeviceProxy::write_attribute,
             ( arg_("self"), arg_("attr_info"), arg_("value") ) )
 
@@ -590,7 +591,7 @@ void export_device_proxy()
 
         .def("polling_status", &Tango::DeviceProxy::polling_status,
             ( arg_("self") ),
-            return_value_policy<manage_new_object>() )
+            bopy::return_value_policy<bopy::manage_new_object>() )
 
         .def("poll_command",
             (void (Tango::DeviceProxy::*)(const char *, int)) &Tango::DeviceProxy::poll_command,
@@ -628,17 +629,17 @@ void export_device_proxy()
         // Asynchronous methods
         //
         .def("__read_attributes_asynch",
-            (long (*) (Tango::DeviceProxy &, object))
+            (long (*) (Tango::DeviceProxy &, bopy::object))
             &PyDeviceProxy::read_attributes_asynch,
             ( arg_("self"), arg_("attr_names") ) )
 
         .def("read_attributes_reply",
-            (object (*) (Tango::DeviceProxy &, long, PyTango::ExtractAs))
+            (bopy::object (*) (Tango::DeviceProxy &, long, PyTango::ExtractAs))
             &PyDeviceProxy::read_attributes_reply,
             ( arg_("self"), arg_("id"), arg_("extract_as")=PyTango::ExtractAsNumpy ) )
 
         .def("read_attributes_reply",
-            (object (*) (Tango::DeviceProxy &, long, long, PyTango::ExtractAs))
+            (bopy::object (*) (Tango::DeviceProxy &, long, long, PyTango::ExtractAs))
             &PyDeviceProxy::read_attributes_reply,
             ( arg_("self"), arg_("id"), arg_("timeout"), arg_("extract_as")=PyTango::ExtractAsNumpy ) )
 
@@ -647,7 +648,7 @@ void export_device_proxy()
             ( arg_("self"), arg_("req_type") ) )
 
         .def("__write_attributes_asynch",
-            (long (*) (Tango::DeviceProxy &, object))
+            (long (*) (Tango::DeviceProxy &, bopy::object))
             &PyDeviceProxy::write_attributes_asynch,
             ( arg_("self"), arg_("values") ) )
 
@@ -662,12 +663,12 @@ void export_device_proxy()
             ( arg_("self"), arg_("id"), arg_("timeout") ) )
 
         .def("__read_attributes_asynch",
-            (void (*) (object, object, object, PyTango::ExtractAs))
+            (void (*) (bopy::object, bopy::object, bopy::object, PyTango::ExtractAs))
             &PyDeviceProxy::read_attributes_asynch,
             ( arg_("self"), arg_("attr_names"), arg_("callback"), arg_("extract_as")=PyTango::ExtractAsNumpy ) )
 
         .def("__write_attributes_asynch",
-            (void (*) (object, object, object))
+            (void (*) (bopy::object, bopy::object, bopy::object))
             &PyDeviceProxy::write_attributes_asynch,
             ( arg_("self"), arg_("values"), arg_("callback") ) )
         
@@ -701,7 +702,7 @@ void export_device_proxy()
                 arg_("attr_name"),
                 arg_("event"),
                 arg_("cb_or_queuesize"),
-                arg_("filters")=boost::python::list(),
+                arg_("filters")=bopy::list(),
                 arg_("stateless")=false,
                 arg_("extract_as")=PyTango::ExtractAsNumpy )
             )
@@ -752,6 +753,6 @@ void export_device_proxy()
             ( arg_("self"), arg_("lockinfo") ))
 
         /// This is to be used by the python layer of this api...
-        //.setattr("__subscribed_events", boost::python::dict())
+        //.setattr("__subscribed_events", bopy::dict())
         ;
 }
diff --git a/src/exception.cpp b/src/exception.cpp
index b1fd337..ab86894 100644
--- a/src/exception.cpp
+++ b/src/exception.cpp
@@ -181,48 +181,39 @@ Tango::DevFailed to_dev_failed(PyObject *type, PyObject *value,
         PyObject *tracebackModule = PyImport_ImportModule("traceback");
         if (tracebackModule != NULL)
         {
-            PyObject *tbList, *emptyString, *strRetval;
-
             //
             // Format the traceback part of the Python exception
             // and store it in the origin part of the Tango exception
             //
 
-            tbList = PyObject_CallMethod(
+            PyObject *tbList_ptr = PyObject_CallMethod(
                     tracebackModule,
                     (char *)"format_tb",
                     (char *)"O",
                     traceback == NULL ? Py_None : traceback);
-
-            emptyString = PyString_FromString("");
-            strRetval = PyObject_CallMethod(emptyString, (char *)"join", (char *)"O", tbList);
-
-            dev_err[0].origin = CORBA::string_dup(PyString_AsString(strRetval));
-
-            Py_DECREF(tbList);
-            Py_DECREF(emptyString);
-            Py_DECREF(strRetval);
+            
+            boost::python::object tbList = object(handle<>(tbList_ptr));
+            boost::python::str origin = str("").join(tbList);
+            char const* origin_ptr = boost::python::extract<char const*>(origin);
+            dev_err[0].origin = CORBA::string_dup(origin_ptr);
 
             //
             // Format the exec and value part of the Python exception
             // and store it in the desc part of the Tango exception
             //
 
-            tbList = PyObject_CallMethod(
+            tbList_ptr = PyObject_CallMethod(
                     tracebackModule,
                     (char *)"format_exception_only",
                     (char *)"OO",
                     type,
                     value == NULL ? Py_None : value);
+            
+            tbList = object(handle<>(tbList_ptr));
+            boost::python::str desc = str("").join(tbList);
+            char const* desc_ptr = boost::python::extract<char const*>(desc);
+            dev_err[0].desc = CORBA::string_dup(desc_ptr);
 
-            emptyString = PyString_FromString("");
-            strRetval = PyObject_CallMethod(emptyString, (char *)"join", (char *)"O", tbList);
-
-            dev_err[0].desc = CORBA::string_dup(PyString_AsString(strRetval));
-
-            Py_DECREF(tbList);
-            Py_DECREF(emptyString);
-            Py_DECREF(strRetval);
             Py_DECREF(tracebackModule);
 
             dev_err[0].reason = CORBA::string_dup("PyDs_PythonError");
diff --git a/src/fast_from_py.h b/src/fast_from_py.h
index 8d96be8..61ac155 100644
--- a/src/fast_from_py.h
+++ b/src/fast_from_py.h
@@ -176,18 +176,6 @@ DEFINE_FAST_TANGO_FROMPY_NUM(Tango::DEV_ULONG64, Tango::DevULong64, PyLong_AsUns
 DEFINE_FAST_TANGO_FROMPY_NUM(Tango::DEV_FLOAT, double, PyFloat_AsDouble)
 DEFINE_FAST_TANGO_FROMPY_NUM(Tango::DEV_DOUBLE, double, PyFloat_AsDouble)
 
-/// @bug Not a bug per se, but you should keep in mind: It returns a new
-/// string, so if you pass it to Tango with a release flag there will be
-/// no problems, but if you have to use it yourself then you must remember
-/// to delete[] it!
-inline Tango::DevString PyString_AsCorbaString(PyObject* ob)
-{
-    const char* str = PyString_AsString(ob);
-    if (!str)
-        return 0;
-    return CORBA::string_dup(str);
-}
-
 // DEFINE_FAST_TANGO_FROMPY(Tango::DEV_STRING, PyString_AsString)
 DEFINE_FAST_TANGO_FROMPY(Tango::DEV_STRING, PyString_AsCorbaString)
 
@@ -679,13 +667,13 @@ inline TANGO_const2type(Tango::DEVVAR_LONGSTRINGARRAY)* fast_convert2array<Tango
         &py_lng = py_value[0],
         &py_str = py_value[1];
 
-    std::auto_ptr<Tango::DevVarLongArray> a_lng(
+    unique_pointer<Tango::DevVarLongArray> a_lng(
         fast_convert2array<Tango::DEVVAR_LONGARRAY>(py_lng));
 
-    std::auto_ptr<Tango::DevVarStringArray> a_str(
+    unique_pointer<Tango::DevVarStringArray> a_str(
         fast_convert2array<Tango::DEVVAR_STRINGARRAY>(py_str));
 
-    std::auto_ptr<TangoArrayType> result(new TangoArrayType());
+    unique_pointer<TangoArrayType> result(new TangoArrayType());
 
     result->lvalue = *a_lng;
     result->svalue = *a_str;
@@ -714,13 +702,13 @@ inline TANGO_const2type(Tango::DEVVAR_DOUBLESTRINGARRAY)* fast_convert2array<Tan
         &py_dbl = py_value[0],
         &py_str = py_value[1];
 
-    std::auto_ptr<Tango::DevVarDoubleArray> a_dbl(
+    unique_pointer<Tango::DevVarDoubleArray> a_dbl(
         fast_convert2array<Tango::DEVVAR_DOUBLEARRAY>(py_dbl));
 
-    std::auto_ptr<Tango::DevVarStringArray> a_str(
+    unique_pointer<Tango::DevVarStringArray> a_str(
         fast_convert2array<Tango::DEVVAR_STRINGARRAY>(py_str));
 
-    std::auto_ptr<TangoArrayType> result(new TangoArrayType());
+    unique_pointer<TangoArrayType> result(new TangoArrayType());
 
     result->dvalue = *a_dbl;
     result->svalue = *a_str;
diff --git a/src/from_py.cpp b/src/from_py.cpp
index c0b0728..b13bcc7 100644
--- a/src/from_py.cpp
+++ b/src/from_py.cpp
@@ -26,6 +26,55 @@
 
 using namespace boost::python;
 
+char* obj_to_new_char(PyObject* obj_ptr)
+{
+    Tango::DevString ret = NULL;
+    if(PyUnicode_Check(obj_ptr))
+    {
+        PyObject* obj_bytes_ptr = PyUnicode_AsLatin1String(obj_ptr);
+        ret = CORBA::string_dup(PyBytes_AsString(obj_bytes_ptr));
+        Py_DECREF(obj_bytes_ptr);
+    }
+    else
+    {
+        ret = CORBA::string_dup(PyBytes_AsString(obj_ptr));
+    }
+    return ret;
+}
+
+char* obj_to_new_char(bopy::object obj)
+{
+    return obj_to_new_char(obj.ptr());
+}
+
+void obj_to_string(PyObject* obj_ptr, std::string& result)
+{
+    if(PyUnicode_Check(obj_ptr))
+    {
+        PyObject* obj_bytes_ptr = PyUnicode_AsLatin1String(obj_ptr);
+        result = PyBytes_AsString(obj_bytes_ptr);
+        Py_DECREF(obj_bytes_ptr);
+    }
+    else
+    {
+        result = PyBytes_AsString(obj_ptr);
+    }
+}
+
+void obj_to_string(bopy::object obj, std::string& result)
+{
+    return obj_to_string(obj.ptr(), result);
+}
+
+/// @bug Not a bug per se, but you should keep in mind: It returns a new
+/// string, so if you pass it to Tango with a release flag there will be
+/// no problems, but if you have to use it yourself then you must remember
+/// to delete[] it!
+Tango::DevString PyString_AsCorbaString(PyObject* obj_ptr)
+{
+    return obj_to_new_char(obj_ptr);
+}
+
 void convert2array(const boost::python::object &py_value, Tango::DevVarCharArray & result)
 {
     PyObject *py_value_ptr = py_value.ptr();
@@ -36,9 +85,9 @@ void convert2array(const boost::python::object &py_value, Tango::DevVarCharArray
 
     size_t size = boost::python::len(py_value);
     result.length(size);
-    if (PyString_Check(py_value_ptr))
+    if (PyBytes_Check(py_value_ptr))
     {
-        char *ch = PyString_AS_STRING(py_value_ptr);
+        char *ch = PyBytes_AS_STRING(py_value_ptr);
         for (size_t i=0; i < size; ++i) {
             result[i] = ch[i];
         }
@@ -60,9 +109,15 @@ void convert2array(const object &py_value, StdStringVector & result)
         raise_(PyExc_TypeError, param_must_be_seq);
     }
     
-    if (PyString_Check(py_value_ptr))
+    if (PyBytes_Check(py_value_ptr))
     {
-        result.push_back(PyString_AsString(py_value_ptr));
+        result.push_back(PyBytes_AS_STRING(py_value_ptr));
+    }
+    else if(PyUnicode_Check(py_value_ptr))
+    {
+        PyObject* py_bytes_value_ptr = PyUnicode_AsLatin1String(py_value_ptr);
+        result.push_back(PyBytes_AS_STRING(py_bytes_value_ptr));
+        Py_DECREF(py_bytes_value_ptr);
     }
     else
     {
@@ -84,10 +139,16 @@ void convert2array(const object &py_value, Tango::DevVarStringArray & result)
         raise_(PyExc_TypeError, param_must_be_seq);
     }
     
-    if (PyString_Check(py_value_ptr))
+    if (PyBytes_Check(py_value_ptr))
     {
         result.length(1);
-        result[0] = CORBA::string_dup(PyString_AsString(py_value_ptr));
+        result[0] = CORBA::string_dup(PyBytes_AS_STRING(py_value_ptr));
+    }
+    else if(PyUnicode_Check(py_value_ptr))
+    {
+        PyObject* py_bytes_value_ptr = PyUnicode_AsLatin1String(py_value_ptr);
+        result[0] = CORBA::string_dup(PyBytes_AS_STRING(py_bytes_value_ptr));
+        Py_DECREF(py_bytes_value_ptr);
     }
     else
     {
@@ -141,35 +202,35 @@ void convert2array(const boost::python::object &py_value, Tango::DevVarLongStrin
     convert2array(py_str, result.svalue);
 }
 
-void from_py_object(object &py_obj, Tango::AttributeAlarm &attr_alarm)
+void from_py_object(bopy::object &py_obj, Tango::AttributeAlarm &attr_alarm)
 {
-    attr_alarm.min_alarm = extract<const char *>(py_obj.attr("min_alarm"));
-    attr_alarm.max_alarm = extract<const char *>(py_obj.attr("max_alarm"));
-    attr_alarm.min_warning = extract<const char *>(py_obj.attr("min_warning"));
-    attr_alarm.max_warning = extract<const char *>(py_obj.attr("max_warning"));
-    attr_alarm.delta_t = extract<const char *>(py_obj.attr("delta_t"));
-    attr_alarm.delta_val = extract<const char *>(py_obj.attr("delta_val"));
+    attr_alarm.min_alarm = obj_to_new_char(py_obj.attr("min_alarm"));
+    attr_alarm.max_alarm = obj_to_new_char(py_obj.attr("max_alarm"));
+    attr_alarm.min_warning = obj_to_new_char(py_obj.attr("min_warning"));
+    attr_alarm.max_warning = obj_to_new_char(py_obj.attr("max_warning"));
+    attr_alarm.delta_t = obj_to_new_char(py_obj.attr("delta_t"));
+    attr_alarm.delta_val = obj_to_new_char(py_obj.attr("delta_val"));
     convert2array(py_obj.attr("extensions"), attr_alarm.extensions);
 }
 
 void from_py_object(object &py_obj, Tango::ChangeEventProp &change_evt_prop)
 {
-    change_evt_prop.rel_change = extract<const char *>(py_obj.attr("rel_change"));
-    change_evt_prop.abs_change = extract<const char *>(py_obj.attr("abs_change"));
+    change_evt_prop.rel_change = obj_to_new_char(py_obj.attr("rel_change"));
+    change_evt_prop.abs_change = obj_to_new_char(py_obj.attr("abs_change"));
     convert2array(py_obj.attr("extensions"), change_evt_prop.extensions);
 }
 
 void from_py_object(object &py_obj, Tango::PeriodicEventProp &periodic_evt_prop)
 {
-    periodic_evt_prop.period = extract<const char *>(py_obj.attr("period"));
+    periodic_evt_prop.period = obj_to_new_char(py_obj.attr("period"));
     convert2array(py_obj.attr("extensions"), periodic_evt_prop.extensions);
 }
 
 void from_py_object(object &py_obj, Tango::ArchiveEventProp &archive_evt_prop)
 {
-    archive_evt_prop.rel_change = extract<const char *>(py_obj.attr("rel_change"));
-    archive_evt_prop.abs_change = extract<const char *>(py_obj.attr("abs_change"));
-    archive_evt_prop.period = extract<const char *>(py_obj.attr("period"));
+    archive_evt_prop.rel_change = obj_to_new_char(py_obj.attr("rel_change"));
+    archive_evt_prop.abs_change = obj_to_new_char(py_obj.attr("abs_change"));
+    archive_evt_prop.period = obj_to_new_char(py_obj.attr("period"));
     convert2array(py_obj.attr("extensions"), archive_evt_prop.extensions);
 }
 
@@ -187,66 +248,66 @@ void from_py_object(object &py_obj, Tango::EventProperties &evt_props)
 
 void from_py_object(object &py_obj, Tango::AttributeConfig &attr_conf)
 {
-    attr_conf.name = extract<const char *>(py_obj.attr("name"));
+    attr_conf.name = obj_to_new_char(py_obj.attr("name"));
     attr_conf.writable = extract<Tango::AttrWriteType>(py_obj.attr("writable"));
     attr_conf.data_format = extract<Tango::AttrDataFormat>(py_obj.attr("data_format"));
     attr_conf.data_type = extract<CORBA::Long>(py_obj.attr("data_type"));
     attr_conf.max_dim_x = extract<CORBA::Long>(py_obj.attr("max_dim_x"));
     attr_conf.max_dim_y = extract<CORBA::Long>(py_obj.attr("max_dim_y"));
-    attr_conf.description = extract<const char *>(py_obj.attr("description"));
-    attr_conf.label = extract<const char *>(py_obj.attr("label"));
-    attr_conf.unit = extract<const char *>(py_obj.attr("unit"));
-    attr_conf.standard_unit = extract<const char *>(py_obj.attr("standard_unit"));
-    attr_conf.display_unit = extract<const char *>(py_obj.attr("display_unit"));
-    attr_conf.format = extract<const char *>(py_obj.attr("format"));
-    attr_conf.min_value = extract<const char *>(py_obj.attr("min_value"));
-    attr_conf.max_value = extract<const char *>(py_obj.attr("max_value"));
-    attr_conf.min_alarm = extract<const char *>(py_obj.attr("min_alarm"));
-    attr_conf.max_alarm = extract<const char *>(py_obj.attr("max_alarm"));
-    attr_conf.writable_attr_name = extract<const char *>(py_obj.attr("writable_attr_name"));
+    attr_conf.description = obj_to_new_char(py_obj.attr("description"));
+    attr_conf.label = obj_to_new_char(py_obj.attr("label"));
+    attr_conf.unit = obj_to_new_char(py_obj.attr("unit"));
+    attr_conf.standard_unit = obj_to_new_char(py_obj.attr("standard_unit"));
+    attr_conf.display_unit = obj_to_new_char(py_obj.attr("display_unit"));
+    attr_conf.format = obj_to_new_char(py_obj.attr("format"));
+    attr_conf.min_value = obj_to_new_char(py_obj.attr("min_value"));
+    attr_conf.max_value = obj_to_new_char(py_obj.attr("max_value"));
+    attr_conf.min_alarm = obj_to_new_char(py_obj.attr("min_alarm"));
+    attr_conf.max_alarm = obj_to_new_char(py_obj.attr("max_alarm"));
+    attr_conf.writable_attr_name = obj_to_new_char(py_obj.attr("writable_attr_name"));
     convert2array(py_obj.attr("extensions"), attr_conf.extensions);
 }
 
 void from_py_object(object &py_obj, Tango::AttributeConfig_2 &attr_conf)
 {
-    attr_conf.name = extract<const char *>(py_obj.attr("name"));
+    attr_conf.name = obj_to_new_char(py_obj.attr("name"));
     attr_conf.writable = extract<Tango::AttrWriteType>(py_obj.attr("writable"));
     attr_conf.data_format = extract<Tango::AttrDataFormat>(py_obj.attr("data_format"));
     attr_conf.data_type = extract<CORBA::Long>(py_obj.attr("data_type"));
     attr_conf.max_dim_x = extract<CORBA::Long>(py_obj.attr("max_dim_x"));
     attr_conf.max_dim_y = extract<CORBA::Long>(py_obj.attr("max_dim_y"));
-    attr_conf.description = extract<const char *>(py_obj.attr("description"));
-    attr_conf.label = extract<const char *>(py_obj.attr("label"));
-    attr_conf.unit = extract<const char *>(py_obj.attr("unit"));
-    attr_conf.standard_unit = extract<const char *>(py_obj.attr("standard_unit"));
-    attr_conf.display_unit = extract<const char *>(py_obj.attr("display_unit"));
-    attr_conf.format = extract<const char *>(py_obj.attr("format"));
-    attr_conf.min_value = extract<const char *>(py_obj.attr("min_value"));
-    attr_conf.max_value = extract<const char *>(py_obj.attr("max_value"));
-    attr_conf.min_alarm = extract<const char *>(py_obj.attr("min_alarm"));
-    attr_conf.max_alarm = extract<const char *>(py_obj.attr("max_alarm"));
-    attr_conf.writable_attr_name = extract<const char *>(py_obj.attr("writable_attr_name"));
+    attr_conf.description = obj_to_new_char(py_obj.attr("description"));
+    attr_conf.label = obj_to_new_char(py_obj.attr("label"));
+    attr_conf.unit = obj_to_new_char(py_obj.attr("unit"));
+    attr_conf.standard_unit = obj_to_new_char(py_obj.attr("standard_unit"));
+    attr_conf.display_unit = obj_to_new_char(py_obj.attr("display_unit"));
+    attr_conf.format = obj_to_new_char(py_obj.attr("format"));
+    attr_conf.min_value = obj_to_new_char(py_obj.attr("min_value"));
+    attr_conf.max_value = obj_to_new_char(py_obj.attr("max_value"));
+    attr_conf.min_alarm = obj_to_new_char(py_obj.attr("min_alarm"));
+    attr_conf.max_alarm = obj_to_new_char(py_obj.attr("max_alarm"));
+    attr_conf.writable_attr_name = obj_to_new_char(py_obj.attr("writable_attr_name"));
     attr_conf.level = extract<Tango::DispLevel>(py_obj.attr("level"));
     convert2array(py_obj.attr("extensions"), attr_conf.extensions);
 }
 
 void from_py_object(object &py_obj, Tango::AttributeConfig_3 &attr_conf)
 {
-    attr_conf.name = extract<const char *>(py_obj.attr("name"));
+    attr_conf.name = obj_to_new_char(py_obj.attr("name"));
     attr_conf.writable = extract<Tango::AttrWriteType>(py_obj.attr("writable"));
     attr_conf.data_format = extract<Tango::AttrDataFormat>(py_obj.attr("data_format"));
     attr_conf.data_type = extract<CORBA::Long>(py_obj.attr("data_type"));
     attr_conf.max_dim_x = extract<CORBA::Long>(py_obj.attr("max_dim_x"));
     attr_conf.max_dim_y = extract<CORBA::Long>(py_obj.attr("max_dim_y"));
-    attr_conf.description = extract<const char *>(py_obj.attr("description"));
-    attr_conf.label = extract<const char *>(py_obj.attr("label"));
-    attr_conf.unit = extract<const char *>(py_obj.attr("unit"));
-    attr_conf.standard_unit = extract<const char *>(py_obj.attr("standard_unit"));
-    attr_conf.display_unit = extract<const char *>(py_obj.attr("display_unit"));
-    attr_conf.format = extract<const char *>(py_obj.attr("format"));
-    attr_conf.min_value = extract<const char *>(py_obj.attr("min_value"));
-    attr_conf.max_value = extract<const char *>(py_obj.attr("max_value"));
-    attr_conf.writable_attr_name = extract<const char *>(py_obj.attr("writable_attr_name"));
+    attr_conf.description = obj_to_new_char(py_obj.attr("description"));
+    attr_conf.label = obj_to_new_char(py_obj.attr("label"));
+    attr_conf.unit = obj_to_new_char(py_obj.attr("unit"));
+    attr_conf.standard_unit = obj_to_new_char(py_obj.attr("standard_unit"));
+    attr_conf.display_unit = obj_to_new_char(py_obj.attr("display_unit"));
+    attr_conf.format = obj_to_new_char(py_obj.attr("format"));
+    attr_conf.min_value = obj_to_new_char(py_obj.attr("min_value"));
+    attr_conf.max_value = obj_to_new_char(py_obj.attr("max_value"));
+    attr_conf.writable_attr_name = obj_to_new_char(py_obj.attr("writable_attr_name"));
     attr_conf.level = extract<Tango::DispLevel>(py_obj.attr("level"));
     
     object py_att_alarm = py_obj.attr("att_alarm");
diff --git a/src/from_py.h b/src/from_py.h
index 269d580..e0c0c21 100644
--- a/src/from_py.h
+++ b/src/from_py.h
@@ -38,6 +38,20 @@
 
 extern const char *param_must_be_seq;
 
+char* obj_to_new_char(PyObject* obj_ptr);
+
+char* obj_to_new_char(bopy::object obj);
+
+void obj_to_string(PyObject* obj_ptr, std::string& result);
+
+void obj_to_string(bopy::object obj, std::string& result);
+
+/// @bug Not a bug per se, but you should keep in mind: It returns a new
+/// string, so if you pass it to Tango with a release flag there will be
+/// no problems, but if you have to use it yourself then you must remember
+/// to delete[] it!
+Tango::DevString PyString_AsCorbaString(PyObject* obj_ptr);
+
 /**
  * Converter from python sequence of strings to a std::vector<std::string>
  *
@@ -140,8 +154,16 @@ struct from_sequence
         for(Py_ssize_t i = 0; i < len; ++i)
         {
             PyObject *o_ptr = PySequence_GetItem(seq_ptr, i);
-            a.push_back(Tango::DbDatum(PyString_AsString(o_ptr)));
-            boost::python::decref(o_ptr);
+            if (PyBytes_Check(o_ptr))
+            {
+                a.push_back(Tango::DbDatum(PyBytes_AS_STRING(o_ptr)));
+            }
+            else if(PyUnicode_Check(o_ptr))
+            {
+                PyObject* o_bytes_ptr = PyUnicode_AsLatin1String(o_ptr);
+                a.push_back(Tango::DbDatum(PyBytes_AS_STRING(o_bytes_ptr)));
+                Py_DECREF(o_bytes_ptr);
+            }
         }
     }
 
@@ -169,7 +191,6 @@ struct from_sequence
             boost::python::tuple pair = (boost::python::tuple)it.attr("next")();
             boost::python::object key = pair[0];
             boost::python::object value = pair[1];
-            PyObject *value_ptr = value.ptr();
 
             boost::python::extract<Tango::DbDatum> ext(value);
             if(ext.check())
@@ -177,16 +198,28 @@ struct from_sequence
                 db_data.push_back(ext());
                 continue;
             }
-
-            Tango::DbDatum db_datum(PyString_AsString(key.ptr()));
-            if((PySequence_Check(value_ptr)) && (!PyString_Check(value_ptr)))
+            
+            char const* key_str = boost::python::extract<char const*>(key);
+            Tango::DbDatum db_datum(key_str);
+            
+            boost::python::extract<char const*> value_str(value);
+            
+            if(value_str.check())
             {
-                from_sequence<StdStringVector>::convert(value, db_datum.value_string);
+                db_datum.value_string.push_back(value_str());
             }
             else
             {
-                boost::python::object value_str = value.attr("__str__")();
-                db_datum.value_string.push_back(PyString_AsString(value_str.ptr()));
+                if(PySequence_Check(value.ptr()))
+                {
+                    from_sequence<StdStringVector>::convert(value, db_datum.value_string);
+                }
+                else
+                {
+                    boost::python::object str_value = value.attr("__str__")();
+                    boost::python::extract<char const*> str_value_str(str_value);
+                    db_datum.value_string.push_back(str_value_str());
+                }
             }
             db_data.push_back(db_datum);
         }
@@ -218,13 +251,15 @@ class CSequenceFromPython
         } else {
             if (PySequence_Check(py_obj.ptr()) == 0)
                 raise_(PyExc_TypeError, param_must_be_seq);
-            if (PyString_Check(py_obj.ptr()) != 0)
+            if (PyUnicode_Check(py_obj.ptr()) != 0)
+                raise_(PyExc_TypeError, param_must_be_seq);
+            if (PyUnicode_Check(py_obj.ptr()) != 0)
                 raise_(PyExc_TypeError, param_must_be_seq);
 
             m_own = true;
             //m_seq = new SequenceT(PySequence_Length(Py_obj.ptr()));
             m_seq = new SequenceT();
-            std::auto_ptr<SequenceT> guard(m_seq);
+            unique_pointer<SequenceT> guard(m_seq);
             from_sequence<SequenceT>::convert(py_obj, *m_seq);
             guard.release();
         }
@@ -254,6 +289,425 @@ void from_py_object(boost::python::object &, Tango::AttributeConfig &);
 void from_py_object(boost::python::object &, Tango::AttributeConfig_2 &);
 void from_py_object(boost::python::object &, Tango::AttributeConfig_3 &);
 
+template<typename T>
+void from_py_object(boost::python::object &py_obj, Tango::MultiAttrProp<T> &multi_attr_prop)
+{
+	multi_attr_prop.label = bopy::extract<string>(bopy::str(py_obj.attr("label")));
+	multi_attr_prop.description = bopy::extract<string>(bopy::str(py_obj.attr("description")));
+	multi_attr_prop.unit = bopy::extract<string>(bopy::str(py_obj.attr("unit")));
+	multi_attr_prop.standard_unit = bopy::extract<string>(bopy::str(py_obj.attr("standard_unit")));
+	multi_attr_prop.display_unit = bopy::extract<string>(bopy::str(py_obj.attr("display_unit")));
+	multi_attr_prop.format = bopy::extract<string>(bopy::str(py_obj.attr("format")));
+
+	bopy::extract<string> min_value(py_obj.attr("min_value"));
+	if(min_value.check())
+		multi_attr_prop.min_value = min_value();
+	else
+		multi_attr_prop.min_value = boost::python::extract<T>(py_obj.attr("min_value"));
+
+	bopy::extract<string> max_value(py_obj.attr("max_value"));
+	if(max_value.check())
+		multi_attr_prop.max_value = max_value();
+	else
+		multi_attr_prop.max_value = boost::python::extract<T>(py_obj.attr("max_value"));
+
+	bopy::extract<string> min_alarm(py_obj.attr("min_alarm"));
+	if(min_alarm.check())
+		multi_attr_prop.min_alarm = min_alarm();
+	else
+		multi_attr_prop.min_alarm = boost::python::extract<T>(py_obj.attr("min_alarm"));
+
+	bopy::extract<string> max_alarm(py_obj.attr("max_alarm"));
+	if(max_alarm.check())
+		multi_attr_prop.max_alarm = max_alarm();
+	else
+		multi_attr_prop.max_alarm = boost::python::extract<T>(py_obj.attr("max_alarm"));
+
+	bopy::extract<string> min_warning(py_obj.attr("min_warning"));
+	if(min_warning.check())
+		multi_attr_prop.min_warning = min_warning();
+	else
+		multi_attr_prop.min_warning = boost::python::extract<T>(py_obj.attr("min_warning"));
+
+	bopy::extract<string> max_warning(py_obj.attr("max_warning"));
+	if(max_warning.check())
+		multi_attr_prop.max_warning = max_warning();
+	else
+		multi_attr_prop.max_warning = boost::python::extract<T>(py_obj.attr("max_warning"));
+
+	bopy::extract<string> delta_t(py_obj.attr("delta_t"));
+	if(delta_t.check())
+		multi_attr_prop.delta_t = delta_t();
+	else
+		multi_attr_prop.delta_t = boost::python::extract<Tango::DevLong>(py_obj.attr("delta_t")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> delta_val(py_obj.attr("delta_val"));
+	if(delta_val.check())
+		multi_attr_prop.delta_val = delta_val();
+	else
+		multi_attr_prop.delta_val = boost::python::extract<T>(py_obj.attr("delta_val"));
+
+	bopy::extract<string> event_period(py_obj.attr("event_period"));
+	if(event_period.check())
+		multi_attr_prop.event_period = event_period();
+	else
+		multi_attr_prop.event_period = boost::python::extract<Tango::DevLong>(py_obj.attr("event_period")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> archive_period(py_obj.attr("archive_period"));
+	if(archive_period.check())
+		multi_attr_prop.archive_period = archive_period();
+	else
+		multi_attr_prop.archive_period = boost::python::extract<Tango::DevLong>(py_obj.attr("archive_period")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> rel_change(py_obj.attr("rel_change"));
+	if(rel_change.check())
+		multi_attr_prop.rel_change = rel_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("rel_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.rel_change = change_vec;
+		}
+		else
+			multi_attr_prop.rel_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("rel_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> abs_change(py_obj.attr("abs_change"));
+	if(abs_change.check())
+		multi_attr_prop.abs_change = abs_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("abs_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.abs_change = change_vec;
+		}
+		else
+			multi_attr_prop.abs_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("abs_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> archive_rel_change(py_obj.attr("archive_rel_change"));
+	if(archive_rel_change.check())
+		multi_attr_prop.archive_rel_change = archive_rel_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("archive_rel_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.archive_rel_change = change_vec;
+		}
+		else
+			multi_attr_prop.archive_rel_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("archive_rel_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> archive_abs_change(py_obj.attr("archive_abs_change"));
+	if(archive_abs_change.check())
+		multi_attr_prop.archive_abs_change = archive_abs_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("archive_abs_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.archive_abs_change = change_vec;
+		}
+		else
+			multi_attr_prop.archive_abs_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("archive_abs_change")); // Property type is Tango::DevDouble!
+	}
+}
+
+template<>
+inline void from_py_object(boost::python::object &py_obj, Tango::MultiAttrProp<Tango::DevEncoded> &multi_attr_prop)
+{
+	multi_attr_prop.label = bopy::extract<string>(bopy::str(py_obj.attr("label")));
+	multi_attr_prop.description = bopy::extract<string>(bopy::str(py_obj.attr("description")));
+	multi_attr_prop.unit = bopy::extract<string>(bopy::str(py_obj.attr("unit")));
+	multi_attr_prop.standard_unit = bopy::extract<string>(bopy::str(py_obj.attr("standard_unit")));
+	multi_attr_prop.display_unit = bopy::extract<string>(bopy::str(py_obj.attr("display_unit")));
+	multi_attr_prop.format = bopy::extract<string>(bopy::str(py_obj.attr("format")));
+
+	bopy::extract<string> min_value(py_obj.attr("min_value"));
+	if(min_value.check())
+		multi_attr_prop.min_value = min_value();
+	else
+		multi_attr_prop.min_value = boost::python::extract<Tango::DevUChar>(py_obj.attr("min_value"));
+
+	bopy::extract<string> max_value(py_obj.attr("max_value"));
+	if(max_value.check())
+		multi_attr_prop.max_value = max_value();
+	else
+		multi_attr_prop.max_value = boost::python::extract<Tango::DevUChar>(py_obj.attr("max_value"));
+
+	bopy::extract<string> min_alarm(py_obj.attr("min_alarm"));
+	if(min_alarm.check())
+		multi_attr_prop.min_alarm = min_alarm();
+	else
+		multi_attr_prop.min_alarm = boost::python::extract<Tango::DevUChar>(py_obj.attr("min_alarm"));
+
+	bopy::extract<string> max_alarm(py_obj.attr("max_alarm"));
+	if(max_alarm.check())
+		multi_attr_prop.max_alarm = max_alarm();
+	else
+		multi_attr_prop.max_alarm = boost::python::extract<Tango::DevUChar>(py_obj.attr("max_alarm"));
+
+	bopy::extract<string> min_warning(py_obj.attr("min_warning"));
+	if(min_warning.check())
+		multi_attr_prop.min_warning = min_warning();
+	else
+		multi_attr_prop.min_warning = boost::python::extract<Tango::DevUChar>(py_obj.attr("min_warning"));
+
+	bopy::extract<string> max_warning(py_obj.attr("max_warning"));
+	if(max_warning.check())
+		multi_attr_prop.max_warning = max_warning();
+	else
+		multi_attr_prop.max_warning = boost::python::extract<Tango::DevUChar>(py_obj.attr("max_warning"));
+
+	bopy::extract<string> delta_t(py_obj.attr("delta_t"));
+	if(delta_t.check())
+		multi_attr_prop.delta_t = delta_t();
+	else
+		multi_attr_prop.delta_t = boost::python::extract<Tango::DevLong>(py_obj.attr("delta_t")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> delta_val(py_obj.attr("delta_val"));
+	if(delta_val.check())
+		multi_attr_prop.delta_val = delta_val();
+	else
+		multi_attr_prop.delta_val = boost::python::extract<Tango::DevUChar>(py_obj.attr("delta_val"));
+
+	bopy::extract<string> event_period(py_obj.attr("event_period"));
+	if(event_period.check())
+		multi_attr_prop.event_period = event_period();
+	else
+		multi_attr_prop.event_period = boost::python::extract<Tango::DevLong>(py_obj.attr("event_period")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> archive_period(py_obj.attr("archive_period"));
+	if(archive_period.check())
+		multi_attr_prop.archive_period = archive_period();
+	else
+		multi_attr_prop.archive_period = boost::python::extract<Tango::DevLong>(py_obj.attr("archive_period")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> rel_change(py_obj.attr("rel_change"));
+	if(rel_change.check())
+		multi_attr_prop.rel_change = rel_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("rel_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.rel_change = change_vec;
+		}
+		else
+			multi_attr_prop.rel_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("rel_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> abs_change(py_obj.attr("abs_change"));
+	if(abs_change.check())
+		multi_attr_prop.abs_change = abs_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("abs_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.abs_change = change_vec;
+		}
+		else
+			multi_attr_prop.abs_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("abs_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> archive_rel_change(py_obj.attr("archive_rel_change"));
+	if(archive_rel_change.check())
+		multi_attr_prop.archive_rel_change = archive_rel_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("archive_rel_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.archive_rel_change = change_vec;
+		}
+		else
+			multi_attr_prop.archive_rel_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("archive_rel_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> archive_abs_change(py_obj.attr("archive_abs_change"));
+	if(archive_abs_change.check())
+		multi_attr_prop.archive_abs_change = archive_abs_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("archive_abs_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.archive_abs_change = change_vec;
+		}
+		else
+			multi_attr_prop.archive_abs_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("archive_abs_change")); // Property type is Tango::DevDouble!
+	}
+}
+
+template<>
+inline void from_py_object(boost::python::object &py_obj, Tango::MultiAttrProp<Tango::DevString> &multi_attr_prop)
+{
+	string empty_str("");
+
+	multi_attr_prop.label = bopy::extract<string>(bopy::str(py_obj.attr("label")));
+	multi_attr_prop.description = bopy::extract<string>(bopy::str(py_obj.attr("description")));
+	multi_attr_prop.unit = bopy::extract<string>(bopy::str(py_obj.attr("unit")));
+	multi_attr_prop.standard_unit = bopy::extract<string>(bopy::str(py_obj.attr("standard_unit")));
+	multi_attr_prop.display_unit = bopy::extract<string>(bopy::str(py_obj.attr("display_unit")));
+	multi_attr_prop.format = bopy::extract<string>(bopy::str(py_obj.attr("format")));
+
+	bopy::extract<string> min_value(py_obj.attr("min_value"));
+	if(min_value.check())
+		multi_attr_prop.min_value = min_value();
+	else
+		multi_attr_prop.min_value = empty_str;
+
+	bopy::extract<string> max_value(py_obj.attr("max_value"));
+	if(max_value.check())
+		multi_attr_prop.max_value = max_value();
+	else
+		multi_attr_prop.max_value = empty_str;
+
+	bopy::extract<string> min_alarm(py_obj.attr("min_alarm"));
+	if(min_alarm.check())
+		multi_attr_prop.min_alarm = min_alarm();
+	else
+		multi_attr_prop.min_alarm = empty_str;
+
+	bopy::extract<string> max_alarm(py_obj.attr("max_alarm"));
+	if(max_alarm.check())
+		multi_attr_prop.max_alarm = max_alarm();
+	else
+		multi_attr_prop.max_alarm = empty_str;
+
+	bopy::extract<string> min_warning(py_obj.attr("min_warning"));
+	if(min_warning.check())
+		multi_attr_prop.min_warning = min_warning();
+	else
+		multi_attr_prop.min_warning = empty_str;
+
+	bopy::extract<string> max_warning(py_obj.attr("max_warning"));
+	if(max_warning.check())
+		multi_attr_prop.max_warning = max_warning();
+	else
+		multi_attr_prop.max_warning = empty_str;
+
+	bopy::extract<string> delta_t(py_obj.attr("delta_t"));
+	if(delta_t.check())
+		multi_attr_prop.delta_t = delta_t();
+	else
+		multi_attr_prop.delta_t = boost::python::extract<Tango::DevLong>(py_obj.attr("delta_t")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> delta_val(py_obj.attr("delta_val"));
+	if(delta_val.check())
+		multi_attr_prop.delta_val = delta_val();
+	else
+		multi_attr_prop.delta_val = empty_str;
+
+	bopy::extract<string> event_period(py_obj.attr("event_period"));
+	if(event_period.check())
+		multi_attr_prop.event_period = event_period();
+	else
+		multi_attr_prop.event_period = boost::python::extract<Tango::DevLong>(py_obj.attr("event_period")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> archive_period(py_obj.attr("archive_period"));
+	if(archive_period.check())
+		multi_attr_prop.archive_period = archive_period();
+	else
+		multi_attr_prop.archive_period = boost::python::extract<Tango::DevLong>(py_obj.attr("archive_period")); // Property type is Tango::DevLong!
+
+	bopy::extract<string> rel_change(py_obj.attr("rel_change"));
+	if(rel_change.check())
+		multi_attr_prop.rel_change = rel_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("rel_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.rel_change = change_vec;
+		}
+		else
+			multi_attr_prop.rel_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("rel_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> abs_change(py_obj.attr("abs_change"));
+	if(abs_change.check())
+		multi_attr_prop.abs_change = abs_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("abs_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.abs_change = change_vec;
+		}
+		else
+			multi_attr_prop.abs_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("abs_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> archive_rel_change(py_obj.attr("archive_rel_change"));
+	if(archive_rel_change.check())
+		multi_attr_prop.archive_rel_change = archive_rel_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("archive_rel_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.archive_rel_change = change_vec;
+		}
+		else
+			multi_attr_prop.archive_rel_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("archive_rel_change")); // Property type is Tango::DevDouble!
+	}
+
+	bopy::extract<string> archive_abs_change(py_obj.attr("archive_abs_change"));
+	if(archive_abs_change.check())
+		multi_attr_prop.archive_abs_change = archive_abs_change();
+	else
+	{
+		boost::python::object prop_py_obj = boost::python::object(py_obj.attr("archive_abs_change"));
+		if(PySequence_Check(prop_py_obj.ptr()))
+		{
+			vector<Tango::DevDouble> change_vec;
+			for(long i = 0; i < len(prop_py_obj); i++)
+				change_vec.push_back(boost::python::extract<Tango::DevDouble>(prop_py_obj[i]));
+			multi_attr_prop.archive_abs_change = change_vec;
+		}
+		else
+			multi_attr_prop.archive_abs_change = boost::python::extract<Tango::DevDouble>(py_obj.attr("archive_abs_change")); // Property type is Tango::DevDouble!
+	}
+}
+
 void from_py_object(boost::python::object &, Tango::AttributeConfigList &);
 void from_py_object(boost::python::object &, Tango::AttributeConfigList_2 &);
 void from_py_object(boost::python::object &, Tango::AttributeConfigList_3 &);
diff --git a/src/group.cpp b/src/group.cpp
index b497c8e..cc5477c 100644
--- a/src/group.cpp
+++ b/src/group.cpp
@@ -27,7 +27,7 @@
 
 void export_group_reply_list();
 void export_group_reply();
-void export_group_element();
+//void export_group_element();
 
 
 namespace PyGroup
@@ -51,6 +51,120 @@ namespace PyGroup
                     " already been inserted in another group." );
         }
     }
+
+    Tango::GroupCmdReplyList command_inout_reply(Tango::Group &self, long req_id, long timeout_ms)
+    {
+        AutoPythonAllowThreads guard;
+        return self.command_inout_reply(req_id, timeout_ms);
+    }
+
+    static void __update_data_format(Tango::Group &self, Tango::GroupAttrReplyList& r)
+    {
+        // Usually we pass a device_proxy to "convert_to_python" in order to
+        // get the data_format of the DeviceAttribute for Tango versions
+        // older than 7.0. However, GroupAttrReply has no device_proxy to use!
+        // So, we are using update_data_format() in here.
+        // The conver_to_python method is called, without the usual
+        // device_proxy argument, in PyGroupAttrReply::get_data().
+        Tango::GroupAttrReplyList::iterator i, e = r.end();
+        for (i=r.begin(); i != e; ++i) {
+            Tango::DeviceProxy* dev_proxy = self.get_device(i->dev_name());
+            if (!dev_proxy)
+                continue;
+            PyDeviceAttribute::update_data_format( *dev_proxy, &(i->get_data()), 1 );
+        }
+    }
+    
+    Tango::GroupAttrReplyList read_attribute_reply (Tango::Group &self,  long req_id, long timeout_ms = 0 )
+    {
+        Tango::GroupAttrReplyList r;
+        {
+            AutoPythonAllowThreads guard;
+            r = self.read_attribute_reply(req_id, timeout_ms);
+        }
+        __update_data_format(self, r);
+        return r;
+    }
+    
+    Tango::GroupAttrReplyList read_attributes_reply (Tango::Group &self, long req_id, long timeout_ms = 0)
+    {
+        Tango::GroupAttrReplyList r;
+        {
+            AutoPythonAllowThreads guard;
+            r = self.read_attributes_reply(req_id, timeout_ms);
+        }
+        __update_data_format(self, r);
+        return r;
+    }
+
+    long read_attributes_asynch (Tango::Group &self, object py_value, bool forward = true)
+    {
+        StdStringVector r;
+        convert2array(py_value, r);
+        return self.read_attributes_asynch(r, forward);
+    }
+
+    long
+    write_attribute_asynch(Tango::Group &self, const std::string &attr_name,
+                           bopy::object py_value, bool forward = true,
+                           bool multi = false)
+    {
+        Tango::DeviceProxy* dev_proxy = self.get_device(1);
+        // If !dev_proxy (no device added in self or his children) then we
+        // don't initialize dev_attr. As a result, the reply will be empty.
+        /// @todo or should we raise an exception instead?
+        if(!dev_proxy)
+        {   
+            Tango::DeviceAttribute dev_attr;
+            AutoPythonAllowThreads guard;
+            return self.write_attribute_asynch(dev_attr, forward);
+        }
+        
+        if(multi)
+        {
+            if(!PySequence_Check(py_value.ptr()))
+            {
+                raise_(PyExc_TypeError,
+                       "When multi is set, value must be a python sequence "
+                       "(ex: list or tuple)" );
+            }
+            
+            Tango::AttributeInfoEx attr_info;
+            {
+                AutoPythonAllowThreads guard;
+                attr_info = dev_proxy->get_attribute_config(attr_name);
+            }
+                        
+            int attr_nb = bopy::len(py_value);
+            std::vector<Tango::DeviceAttribute> dev_attr(attr_nb);
+            for(int i = 0; i < attr_nb; ++i)
+            {
+                PyDeviceAttribute::reset(dev_attr[i], attr_info, py_value[i]);
+            }
+            
+            AutoPythonAllowThreads guard;
+            return self.write_attribute_asynch(dev_attr, forward);
+        }
+        else
+        {
+            Tango::DeviceAttribute dev_attr;
+            Tango::DeviceProxy* dev_proxy = self.get_device(1);
+            if (dev_proxy)
+                PyDeviceAttribute::reset(dev_attr, attr_name, *dev_proxy, py_value);
+            // If !dev_proxy (no device added in self or his children) then we
+            // don't initialize dev_attr. As a result, the reply will be empty.
+            /// @todo or should we raise an exception instead?
+
+            AutoPythonAllowThreads guard;
+            return self.write_attribute_asynch(dev_attr, forward);
+        }
+    }
+
+    Tango::GroupReplyList write_attribute_reply (Tango::Group &self, long req_id, long timeout_ms = 0)
+    {
+        AutoPythonAllowThreads guard;
+        return self.write_attribute_reply(req_id, timeout_ms);
+    }
 }
 
 void export_group()
@@ -59,25 +173,46 @@ void export_group()
     
     export_group_reply();
     export_group_reply_list();
-    export_group_element();
+//    export_group_element();
 
-    class_<Tango::Group, bases<Tango::GroupElement>, std::auto_ptr<Tango::Group>, boost::noncopyable > Group(
-        "__Group",
-        init<const std::string&>())
+//    class_<Tango::Group, bases<Tango::GroupElement>,
+//           unique_pointer<Tango::Group>, boost::noncopyable > Group(
+//        "__Group",
+//        init<const std::string&>())
+//    ;
+    class_<Tango::Group, std::auto_ptr<Tango::Group>, boost::noncopyable >
+        Group("__Group",
+              init<const std::string&>())
     ;
     
     Group
-        .def("__add",
+        .def("_add",
             (void (Tango::Group::*) (const std::string &, int))
             &Tango::Group::add,
             (arg_("self"), arg_("pattern"), arg_("timeout_ms")=-1) )
-        .def("__add",
+        .def("_add",
             (void (Tango::Group::*) (const std::vector<std::string> &, int))
             &Tango::Group::add,
             (arg_("self"), arg_("patterns"), arg_("timeout_ms")=-1))
-        .def("__add",
+        .def("_add",
             PyGroup::add,
             (arg_("self"), arg_("group"), arg_("timeout_ms")=-1) )
+
+        .def("_remove",
+            (void (Tango::Group::*) (const std::string &, bool))
+            &Tango::Group::remove,
+            (arg_("self"), arg_("pattern"), arg_("forward")=true))
+        .def("_remove",
+            (void (Tango::Group::*) (const std::vector<std::string> &, bool))
+            &Tango::Group::remove,
+            (arg_("self"), arg_("patterns"), arg_("forward")=true))
+        .def("get_group",
+            &Tango::Group::get_group,
+            (arg_("self"), arg_("group_name")),
+            return_internal_reference<1>() )
+        .def("get_size",
+            &Tango::Group::get_size,
+            (arg_("self"), arg_("forward")=true) )
             
         .def("remove_all", &Tango::Group::remove_all)
 
@@ -100,6 +235,115 @@ void export_group()
         .def("get_device_list",
             &Tango::Group::get_device_list,
             (arg_("self"), arg_("forward")=true) )
+
+        .def("command_inout_asynch",
+            (long (Tango::Group::*) (const std::string&, bool, bool))
+            &Tango::Group::command_inout_asynch,
+            (   arg_("self"),
+                arg_("cmd_name"),
+                arg_("forget")=false,
+                arg_("forward")=true) )
+        .def("command_inout_asynch",
+            (long (Tango::Group::*) (const std::string&, const Tango::DeviceData&, bool, bool))
+            &Tango::Group::command_inout_asynch,
+            (   arg_("self"),
+                arg_("cmd_name"),
+                arg_("param"),
+                arg_("forget")=false,
+                arg_("forward")=true) )
+        .def("command_inout_asynch",
+            (long (Tango::Group::*) (const std::string&, const std::vector<Tango::DeviceData>&, bool, bool))
+            &Tango::Group::command_inout_asynch,
+            (   arg_("self"),
+                arg_("cmd_name"),
+                arg_("param"),
+                arg_("forget")=false,
+                arg_("forward")=true) )
+        .def("command_inout_reply",
+            PyGroup::command_inout_reply,
+            (   arg_("self"),
+                arg_("req_id"),
+                arg_("timeout_ms")=0 ) )
+        .def("read_attribute_asynch",
+            &Tango::Group::read_attribute_asynch,
+            (   arg_("self"),
+                arg_("attr_name"),
+                arg_("forward")=true) )
+        .def("read_attribute_reply",
+            PyGroup::read_attribute_reply,
+            (   arg_("self"),
+                arg_("req_id"),
+                arg_("timeout_ms")=0 ) )
+        .def("read_attributes_asynch",
+            PyGroup::read_attributes_asynch,
+            (   arg_("self"),
+                arg_("attr_names"),
+                arg_("forward")=true) )
+        .def("read_attributes_reply",
+            PyGroup::read_attributes_reply,
+            (   arg_("self"),
+                arg_("req_id"),
+                arg_("timeout_ms")=0 ) )
+        .def("write_attribute_asynch",
+            PyGroup::write_attribute_asynch,
+            (   arg_("self"),
+                arg_("attr_name"),
+                arg_("value"),
+                arg_("forward")=true,
+                arg_("multi")=false) )
+        .def("write_attribute_reply",
+            PyGroup::write_attribute_reply,
+            (   arg_("self"),
+                arg_("req_id"),
+                arg_("timeout_ms")=0 ) )
+
+
+         .def("get_parent",
+             &Tango::Group::get_parent,
+             (arg_("self")),
+             return_internal_reference<1>() )
+        .def("contains",
+            &Tango::Group::contains,
+            (arg_("self"), arg_("pattern"), arg_("forward")=true) )
+        .def("get_device",
+            (Tango::DeviceProxy* (Tango::Group::*) (const std::string &))
+            &Tango::Group::get_device,
+            (arg_("self"), arg_("dev_name")),
+            return_internal_reference<1>() )
+        .def("get_device",
+            (Tango::DeviceProxy* (Tango::Group::*) (long))
+            &Tango::Group::get_device,
+            (arg_("self"), arg_("idx")),
+            return_internal_reference<1>() )
+        .def("ping",
+            &Tango::Group::ping,
+            (arg_("self"), arg_("forward")=true) )
+        .def("set_timeout_millis",
+            &Tango::Group::set_timeout_millis,
+            (arg_("self"), arg_("timeout_ms")) )
+        .def("get_name",
+            &Tango::Group::get_name,
+            (arg_("self")),
+            return_value_policy<copy_const_reference>() )
+        .def("get_fully_qualified_name",
+            &Tango::Group::get_fully_qualified_name,
+            (arg_("self")) )
+        .def("enable",
+            &Tango::Group::enable,
+            (arg_("self")) )
+        .def("disable",
+            &Tango::Group::disable,
+            (arg_("self")) )
+        .def("is_enabled",
+            &Tango::Group::is_enabled,
+            (arg_("self")) )
+        .def("name_equals",
+            &Tango::Group::name_equals,
+            (arg_("self")) )
+        .def("name_matches",
+            &Tango::Group::name_matches,
+            (arg_("self")) )
+
     ;
 
     // I am not exporting "find", so all the GroupElemens will be
diff --git a/src/group_element.cpp b/src/group_element.cpp
index 10ad5a4..8378762 100644
--- a/src/group_element.cpp
+++ b/src/group_element.cpp
@@ -25,92 +25,12 @@
 #include "pytgutils.h"
 #include "device_attribute.h"
 
-namespace PyGroupElement
-{
-    using namespace boost::python;
-
-
-    Tango::GroupCmdReplyList command_inout_reply(Tango::GroupElement &self, long req_id, long timeout_ms)
-    {
-        AutoPythonAllowThreads guard;
-        return self.command_inout_reply(req_id, timeout_ms);
-    }
-
-    static void __update_data_format(Tango::GroupElement &self, Tango::GroupAttrReplyList& r)
-    {
-        // Usually we pass a device_proxy to "convert_to_python" in order to
-        // get the data_format of the DeviceAttribute for Tango versions
-        // older than 7.0. However, GroupAttrReply has no device_proxy to use!
-        // So, we are using update_data_format() in here.
-        // The conver_to_python method is called, without the usual
-        // device_proxy argument, in PyGroupAttrReply::get_data().
-        Tango::GroupAttrReplyList::iterator i, e = r.end();
-        for (i=r.begin(); i != e; ++i) {
-            Tango::DeviceProxy* dev_proxy = self.get_device(i->dev_name());
-            if (!dev_proxy)
-                continue;
-            PyDeviceAttribute::update_data_format( *dev_proxy, &(i->get_data()), 1 );
-        }
-    }
-    
-    Tango::GroupAttrReplyList read_attribute_reply (Tango::GroupElement &self,  long req_id, long timeout_ms = 0 )
-    {
-        Tango::GroupAttrReplyList r;
-        {
-            AutoPythonAllowThreads guard;
-            r = self.read_attribute_reply(req_id, timeout_ms);
-        }
-        __update_data_format(self, r);
-        return r;
-    }
-    
-    Tango::GroupAttrReplyList read_attributes_reply (Tango::GroupElement &self, long req_id, long timeout_ms = 0)
-    {
-        Tango::GroupAttrReplyList r;
-        {
-            AutoPythonAllowThreads guard;
-            r = self.read_attributes_reply(req_id, timeout_ms);
-        }
-        __update_data_format(self, r);
-        return r;
-    }
-
-    long read_attributes_asynch (Tango::GroupElement &self, object py_value, bool forward = true, long reserved = -1)
-    {
-        StdStringVector r;
-        convert2array(py_value, r);
-        return self.read_attributes_asynch(r, forward, reserved);
-    }
-
-    long write_attribute_asynch (Tango::GroupElement &self, const std::string &attr_name, object py_value, bool forward = true, long reserved = -1)
-    {
-        Tango::DeviceAttribute dev_attr;
-        Tango::DeviceProxy* dev_proxy = self.get_device(1);
-        if (dev_proxy)
-            PyDeviceAttribute::reset(dev_attr, attr_name, *dev_proxy, py_value);
-        // If !dev_proxy (no device added in self or his children) then we
-        // don't initialize dev_attr. As a result, the reply will be empty.
-        /// @todo or should we raise an exception instead?
-
-        AutoPythonAllowThreads guard;
-        return self.write_attribute_asynch(dev_attr, forward, reserved);
-    }
-
-    Tango::GroupReplyList write_attribute_reply (Tango::GroupElement &self, long req_id, long timeout_ms = 0)
-    {
-        AutoPythonAllowThreads guard;
-        return self.write_attribute_reply(req_id, timeout_ms);
-    }
-    
-    
-}
-
-
 void export_group_element()
 {
     using namespace boost::python;
 
-    class_<Tango::GroupElement, std::auto_ptr<Tango::GroupElement>, boost::noncopyable> GroupElement("GroupElement",
+    class_<Tango::GroupElement, unique_pointer<Tango::GroupElement>,
+           boost::noncopyable> GroupElement("GroupElement",
         "The abstract GroupElement class for Group. Not to be initialized\n"
         "directly.", no_init)
     ;
@@ -119,22 +39,22 @@ void export_group_element()
     //
     // Group management methods
     //
-        .def("__add",
-            (void (Tango::GroupElement::*) (const std::string &, int))
-            &Tango::GroupElement::add,
-            (arg_("self"), arg_("pattern"), arg_("timeout_ms")=-1) )
-        .def("__add",
-            (void (Tango::GroupElement::*) (const std::vector<std::string> &, int))
-            &Tango::GroupElement::add,
-            (arg_("self"), arg_("patterns"), arg_("timeout_ms")=-1))
-        .def("__remove",
-            (void (Tango::GroupElement::*) (const std::string &, bool))
-            &Tango::GroupElement::remove,
-            (arg_("self"), arg_("pattern"), arg_("forward")=true))
-        .def("__remove",
-            (void (Tango::GroupElement::*) (const std::vector<std::string> &, bool))
-            &Tango::GroupElement::remove,
-            (arg_("self"), arg_("patterns"), arg_("forward")=true))
+//        .def("__add",
+//            (void (Tango::GroupElement::*) (const std::string &, int))
+//            &Tango::GroupElement::add,
+//            (arg_("self"), arg_("pattern"), arg_("timeout_ms")=-1) )
+//        .def("__add",
+//            (void (Tango::GroupElement::*) (const std::vector<std::string> &, int))
+//            &Tango::GroupElement::add,
+//            (arg_("self"), arg_("patterns"), arg_("timeout_ms")=-1))
+//        .def("__remove",
+//            (void (Tango::GroupElement::*) (const std::string &, bool))
+//            &Tango::GroupElement::remove,
+//            (arg_("self"), arg_("pattern"), arg_("forward")=true))
+//        .def("__remove",
+//            (void (Tango::GroupElement::*) (const std::vector<std::string> &, bool))
+//            &Tango::GroupElement::remove,
+//            (arg_("self"), arg_("patterns"), arg_("forward")=true))
         .def("contains",
             &Tango::GroupElement::contains,
             (arg_("self"), arg_("pattern"), arg_("forward")=true) )
@@ -148,10 +68,10 @@ void export_group_element()
             &Tango::GroupElement::get_device,
             (arg_("self"), arg_("idx")),
             return_internal_reference<1>() )
-        .def("get_group",
-            &Tango::GroupElement::get_group,
-            (arg_("self"), arg_("group_name")),
-            return_internal_reference<1>() )
+//        .def("get_group",
+//            &Tango::GroupElement::get_group,
+//            (arg_("self"), arg_("group_name")),
+//            return_internal_reference<1>() )
 
     //
     // Tango methods (~ DeviceProxy interface)
@@ -162,62 +82,7 @@ void export_group_element()
         .def("set_timeout_millis",
             pure_virtual(&Tango::GroupElement::set_timeout_millis),
             (arg_("self"), arg_("timeout_ms")) )
-        .def("command_inout_asynch",
-            pure_virtual((long (Tango::GroupElement::*) (const std::string&, bool, bool, long))
-            &Tango::GroupElement::command_inout_asynch),
-            (   arg_("self"),
-                arg_("cmd_name"),
-                arg_("forget")=false,
-                arg_("forward")=true,
-                arg_("reserved")=-1) )
-        .def("command_inout_asynch",
-            pure_virtual((long (Tango::GroupElement::*) (const std::string&, const Tango::DeviceData&, bool, bool, long))
-            &Tango::GroupElement::command_inout_asynch),
-            (   arg_("self"),
-                arg_("cmd_name"),
-                arg_("param"),
-                arg_("forget")=false,
-                arg_("forward")=true,
-                arg_("reserved")=-1) )
-        .def("command_inout_reply",
-            PyGroupElement::command_inout_reply,
-            (   arg_("self"),
-                arg_("req_id"),
-                arg_("timeout_ms")=0 ) )
-        .def("read_attribute_asynch",
-            pure_virtual(&Tango::GroupElement::read_attribute_asynch),
-            (   arg_("self"),
-                arg_("attr_name"),
-                arg_("forward")=true,
-                arg_("reserved")=-1) )
-        .def("read_attribute_reply",
-            &PyGroupElement::read_attribute_reply,
-            (   arg_("self"),
-                arg_("req_id"),
-                arg_("timeout_ms")=0 ) )
-        .def("read_attributes_asynch",
-            PyGroupElement::read_attributes_asynch,
-            (   arg_("self"),
-                arg_("attr_names"),
-                arg_("forward")=true,
-                arg_("reserved")=-1) )
-        .def("read_attributes_reply",
-            PyGroupElement::read_attributes_reply,
-            (   arg_("self"),
-                arg_("req_id"),
-                arg_("timeout_ms")=0 ) )
-        .def("write_attribute_asynch",
-            &PyGroupElement::write_attribute_asynch,
-            (   arg_("self"),
-                arg_("attr_name"),
-                arg_("value"),
-                arg_("forward")=true,
-                arg_("reserved")=-1 ) )
-        .def("write_attribute_reply",
-            PyGroupElement::write_attribute_reply,
-            (   arg_("self"),
-                arg_("req_id"),
-                arg_("timeout_ms")=0 ) )
+
 
     //
     // Misc
@@ -244,9 +109,9 @@ void export_group_element()
         .def("name_matches",
             &Tango::GroupElement::name_matches,
             (arg_("self")) )
-        .def("get_size",
-            &Tango::GroupElement::get_size,
-            (arg_("self"), arg_("forward")=true) )
+//        .def("get_size",
+//            &Tango::GroupElement::get_size,
+//            (arg_("self"), arg_("forward")=true) )
 
     //
     // "Should not be used" methods
diff --git a/src/locker_info.cpp b/src/locker_info.cpp
index a2d998c..1315bda 100644
--- a/src/locker_info.cpp
+++ b/src/locker_info.cpp
@@ -24,21 +24,19 @@
 #include "precompiled_header.hpp"
 #include <tango.h>
 
-using namespace boost::python;
-
 struct PyLockerInfo
 {
-    static inline object get_locker_id(Tango::LockerInfo &li)
+    static inline boost::python::object get_locker_id(Tango::LockerInfo &li)
     {
         return (li.ll == Tango::CPP) ?
-            object(li.li.LockerPid) :
-            tuple(li.li.UUID);
+            boost::python::object(li.li.LockerPid) :
+            boost::python::tuple(li.li.UUID);
     }
 };
 
 void export_locker_info()
 {
-    class_<Tango::LockerInfo>("LockerInfo")
+    boost::python::class_<Tango::LockerInfo>("LockerInfo")
         .def_readonly("ll", &Tango::LockerInfo::ll)
         .add_property("li", &PyLockerInfo::get_locker_id)
         .def_readonly("locker_host", &Tango::LockerInfo::locker_host)
diff --git a/src/pytango.cpp b/src/pytango.cpp
index f3b2544..c330244 100644
--- a/src/pytango.cpp
+++ b/src/pytango.cpp
@@ -35,7 +35,7 @@
 #include <tango.h>
 
 using namespace boost::python;
-
+ 
 void export_version();
 void export_enums();
 void export_constants();
@@ -65,6 +65,13 @@ void export_device_impl();
 void export_group();
 void export_log4tango();
 
+void init_numpy()
+{
+#   ifndef DISABLE_PYTANGO_NUMPY
+        import_array1();
+#   endif
+}
+
 BOOST_PYTHON_MODULE(_PyTango)
 {
 
@@ -83,9 +90,7 @@ BOOST_PYTHON_MODULE(_PyTango)
 
     PyEval_InitThreads();
 
-#   ifndef DISABLE_PYTANGO_NUMPY
-        import_array();
-#   endif
+    init_numpy();
 
     export_callback(); /// @todo not sure were to put it...
 
diff --git a/src/pyutils.cpp b/src/pyutils.cpp
index cfffc9c..fdfa556 100644
--- a/src/pyutils.cpp
+++ b/src/pyutils.cpp
@@ -27,6 +27,63 @@
 
 using namespace boost::python;
 
+bopy::object from_char_to_str2(const std::string& in, 
+                               const char* encoding /*=NULL defaults to latin-1 */,
+                               const char* errors /*="strict" */)
+{
+    return from_char_to_str2(in.c_str(), in.size(), encoding, errors);
+}
+
+bopy::object from_char_to_str2(const char* in, Py_ssize_t size /* =-1 */, 
+                               const char* encoding /*=NULL defaults to latin-1 */,
+                               const char* errors /*="strict" */)
+{
+    return bopy::object(bopy::handle<>(from_char_to_str(in, size, encoding, errors)));
+}
+
+PyObject* from_char_to_str(const std::string& in, 
+                           const char* encoding /*=NULL defaults to latin-1 */,
+                           const char* errors /*="strict" */)
+{
+    return from_char_to_str(in.c_str(), in.size(), encoding, errors);
+}
+
+PyObject* from_char_to_str(const char* in, Py_ssize_t size /* =-1 */, 
+                           const char* encoding /*=NULL defaults to latin-1 */,
+                           const char* errors /*="strict" */)
+{
+if (size < 0)
+{
+    size = strlen(in);
+}
+#ifdef PYTANGO_PY3K
+    if (!encoding)
+    {
+        return PyUnicode_DecodeLatin1(in, size, errors);
+    }
+    else
+    {   
+        return PyUnicode_Decode(in, size, encoding, errors);
+    }
+#else
+    return PyString_FromStringAndSize(in, size);
+#endif
+}
+
+void from_str_to_char(PyObject* in, std::string& out)
+{
+    if (PyUnicode_Check(in))
+    {
+        PyObject *bytes_in = PyUnicode_AsLatin1String(in);
+        out = PyBytes_AsString(bytes_in);
+        Py_DECREF(bytes_in);
+    }
+    else 
+    {
+        out = std::string(PyBytes_AsString(in), PyBytes_Size(in));
+    }
+}
+
 bool is_method_defined(object &obj, const std::string &method_name)
 {
     return is_method_defined(obj.ptr(), method_name);
diff --git a/src/pyutils.h b/src/pyutils.h
index 36c21f1..686dddb 100644
--- a/src/pyutils.h
+++ b/src/pyutils.h
@@ -25,8 +25,14 @@
 
 #include <boost/python.hpp>
 
+namespace bopy = boost::python;
+
 #define arg_(a) boost::python::arg(a)
 
+#if PY_MAJOR_VERSION >= 3
+#define PYTANGO_PY3K
+#endif
+
 #if PY_VERSION_HEX < 0x02050000
 typedef int Py_ssize_t;
 #endif
@@ -56,48 +62,197 @@ inline PyObject *PyImport_ImportModule_(const std::string &name)
     return PyImport_ImportModule(attr);
 }
 
-// -----------------------------------------------------------------------------
-// The following section defines missing symbols in python <3.0 with macros
-
-#if PY_VERSION_HEX < 0x02070000
-    #if PY_VERSION_HEX < 0x02060000
-        #define PyObject_CheckBuffer(object) (0)
-
-        #define PyObject_GetBuffer(obj, view, flags) (PyErr_SetString(PyExc_NotImplementedError, \
-                        "new buffer interface is not available"), -1)
-        #define PyBuffer_FillInfo(view, obj, buf, len, readonly, flags) (PyErr_SetString(PyExc_NotImplementedError, \
-                    "new buffer interface is not available"), -1)
-        #define PyBuffer_Release(obj) (PyErr_SetString(PyExc_NotImplementedError, \
-                        "new buffer interface is not available"), -1)
-        // Bytes->String
-        #define PyBytes_FromStringAndSize PyString_FromStringAndSize
-        #define PyBytes_FromString PyString_FromString
-        #define PyBytes_AsString PyString_AsString
-        #define PyBytes_Size PyString_Size
-    #endif
-
-    #define PyMemoryView_FromBuffer(info) (PyErr_SetString(PyExc_NotImplementedError, \
-                    "new buffer interface is not available"), (PyObject *)NULL)
-    #define PyMemoryView_FromObject(object)     (PyErr_SetString(PyExc_NotImplementedError, \
-                                        "new buffer interface is not available"), (PyObject *)NULL)
+// Bytes interface
+#if PY_VERSION_HEX < 0x02060000
+    #define PyBytesObject PyStringObject
+    #define PyBytes_Type PyString_Type
+
+    #define PyBytes_Check PyString_Check
+    #define PyBytes_CheckExact PyString_CheckExact 
+    #define PyBytes_CHECK_INTERNED PyString_CHECK_INTERNED
+    #define PyBytes_AS_STRING PyString_AS_STRING
+    #define PyBytes_GET_SIZE PyString_GET_SIZE
+    #define Py_TPFLAGS_BYTES_SUBCLASS Py_TPFLAGS_STRING_SUBCLASS
+
+    #define PyBytes_FromStringAndSize PyString_FromStringAndSize
+    #define PyBytes_FromString PyString_FromString
+    #define PyBytes_FromFormatV PyString_FromFormatV
+    #define PyBytes_FromFormat PyString_FromFormat
+    #define PyBytes_Size PyString_Size
+    #define PyBytes_AsString PyString_AsString
+    #define PyBytes_Repr PyString_Repr
+    #define PyBytes_Concat PyString_Concat
+    #define PyBytes_ConcatAndDel PyString_ConcatAndDel
+    #define _PyBytes_Resize _PyString_Resize
+    #define _PyBytes_Eq _PyString_Eq
+    #define PyBytes_Format PyString_Format
+    #define _PyBytes_FormatLong _PyString_FormatLong
+    #define PyBytes_DecodeEscape PyString_DecodeEscape
+    #define _PyBytes_Join _PyString_Join
+    #define PyBytes_Decode PyString_Decode
+    #define PyBytes_Encode PyString_Encode
+    #define PyBytes_AsEncodedObject PyString_AsEncodedObject
+    #define PyBytes_AsEncodedString PyString_AsEncodedString
+    #define PyBytes_AsDecodedObject PyString_AsDecodedObject
+    #define PyBytes_AsDecodedString PyString_AsDecodedString
+    #define PyBytes_AsStringAndSize PyString_AsStringAndSize
+    #define _PyBytes_InsertThousandsGrouping _PyString_InsertThousandsGrouping
+#else
+    #include <bytesobject.h>
 #endif
 
-#if PY_VERSION_HEX >= 0x03000000
-    // for buffers
-    #define Py_END_OF_BUFFER ((Py_ssize_t) 0)
+/* PyCapsule definitions for old python */
 
-    #define PyObject_CheckReadBuffer(object) (0)
+#if (    (PY_VERSION_HEX <  0x02070000) \
+     || ((PY_VERSION_HEX >= 0x03000000) \
+      && (PY_VERSION_HEX <  0x03010000)) )
 
-    #define PyBuffer_FromMemory(ptr, s) (PyErr_SetString(PyExc_NotImplementedError, \
-                            "old buffer interface is not available"), (PyObject *)NULL)
-    #define PyBuffer_FromReadWriteMemory(ptr, s) (PyErr_SetString(PyExc_NotImplementedError, \
-                            "old buffer interface is not available"), (PyObject *)NULL)
-    #define PyBuffer_FromObject(object, offset, size)  (PyErr_SetString(PyExc_NotImplementedError, \
-                            "old buffer interface is not available"), (PyObject *)NULL)
-    #define PyBuffer_FromReadWriteObject(object, offset, size)  (PyErr_SetString(PyExc_NotImplementedError, \
-                            "old buffer interface is not available"), (PyObject *)NULL)
+#define PYCAPSULE_OLD
+
+#define __PyCapsule_GetField(capsule, field, default_value) \
+    ( PyCapsule_CheckExact(capsule) \
+        ? (((PyCObject *)capsule)->field) \
+        : (default_value) \
+    ) \
+
+#define __PyCapsule_SetField(capsule, field, value) \
+    ( PyCapsule_CheckExact(capsule) \
+        ? (((PyCObject *)capsule)->field = value), 1 \
+        : 0 \
+    ) \
+
+
+#define PyCapsule_Type PyCObject_Type
+
+#define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule))
+#define PyCapsule_IsValid(capsule, name) (PyCObject_Check(capsule))
 
-#endif
+
+#define PyCapsule_New(pointer, name, destructor) \
+    (PyCObject_FromVoidPtr(pointer, destructor))
+
+
+#define PyCapsule_GetPointer(capsule, name) \
+    (PyCObject_AsVoidPtr(capsule))
+
+/* Don't call PyCObject_SetPointer here, it fails if there's a destructor */
+#define PyCapsule_SetPointer(capsule, pointer) \
+    __PyCapsule_SetField(capsule, cobject, pointer)
+
+
+#define PyCapsule_GetDestructor(capsule) \
+    __PyCapsule_GetField(capsule, destructor)
+
+#define PyCapsule_SetDestructor(capsule, dtor) \
+    __PyCapsule_SetField(capsule, destructor, dtor)
+
+
+/*
+ * Sorry, there's simply no place
+ * to store a Capsule "name" in a CObject.
+ */
+#define PyCapsule_GetName(capsule) NULL
+
+static int
+PyCapsule_SetName(PyObject *capsule, const char *unused)
+{
+    unused = unused;
+    PyErr_SetString(PyExc_NotImplementedError,
+        "can't use PyCapsule_SetName with CObjects");
+    return 1;
+}
+
+
+
+#define PyCapsule_GetContext(capsule) \
+    __PyCapsule_GetField(capsule, descr)
+
+#define PyCapsule_SetContext(capsule, context) \
+    __PyCapsule_SetField(capsule, descr, context)
+
+
+static void *
+PyCapsule_Import(const char *name, int no_block)
+{
+    PyObject *object = NULL;
+    void *return_value = NULL;
+    char *trace;
+    size_t name_length = (strlen(name) + 1) * sizeof(char);
+    char *name_dup = (char *)PyMem_MALLOC(name_length);
+
+    if (!name_dup) {
+        return NULL;
+    }
+
+    memcpy(name_dup, name, name_length);
+
+    trace = name_dup;
+    while (trace) {
+        char *dot = strchr(trace, '.');
+        if (dot) {
+            *dot++ = '\0';
+        }
+
+        if (object == NULL) {
+            if (no_block) {
+                object = PyImport_ImportModuleNoBlock(trace);
+            } else {
+                object = PyImport_ImportModule(trace);
+                if (!object) {
+                    PyErr_Format(PyExc_ImportError,
+                        "PyCapsule_Import could not "
+                        "import module \"%s\"", trace);
+                }
+            }
+        } else {
+            PyObject *object2 = PyObject_GetAttrString(object, trace);
+            Py_DECREF(object);
+            object = object2;
+        }
+        if (!object) {
+            goto EXIT;
+        }
+
+        trace = dot;
+    }
+
+    if (PyCObject_Check(object)) {
+        PyCObject *cobject = (PyCObject *)object;
+        return_value = cobject->cobject;
+    } else {
+        PyErr_Format(PyExc_AttributeError,
+            "PyCapsule_Import \"%s\" is not valid",
+            name);
+    }
+
+EXIT:
+    Py_XDECREF(object);
+    if (name_dup) {
+        PyMem_FREE(name_dup);
+    }
+    return return_value;
+}
+
+#endif /* #if PY_VERSION_HEX < 0x02070000 */
+
+PyObject* from_char_to_str(const char* in, Py_ssize_t size=-1, 
+                           const char* encoding=NULL, /* defaults to latin-1 */
+                           const char* errors="strict");
+
+PyObject* from_char_to_str(const std::string& in,
+                           const char* encoding=NULL, /* defaults to latin-1 */
+                           const char* errors="strict");
+
+bopy::object from_char_to_str2(const char* in, Py_ssize_t size=-1, 
+                               const char* encoding=NULL, /* defaults to latin-1 */
+                               const char* errors="strict");
+
+bopy::object from_char_to_str2(const std::string& in,
+                               const char* encoding=NULL, /* defaults to latin-1 */
+                               const char* errors="strict");
+
+
+void from_str_to_char(PyObject* in, std::string& out);
 
 inline void raise_(PyObject *type, const char *message)
 {
@@ -113,10 +268,24 @@ class AutoPythonAllowThreads
     
 public:
     
-    inline void giveup() { if (m_save) { PyEval_RestoreThread(m_save); m_save = 0; } }
+    inline void giveup()
+    {
+        if (m_save)
+        {
+            PyEval_RestoreThread(m_save);
+            m_save = 0;
+        }
+    }
+    
+    inline AutoPythonAllowThreads()
+    {
+        m_save = PyEval_SaveThread();
+    }
     
-    inline AutoPythonAllowThreads() { m_save = PyEval_SaveThread(); } ;
-    inline ~AutoPythonAllowThreads() {giveup();} ;
+    inline ~AutoPythonAllowThreads()
+    {
+        giveup();
+    }
 };
 
 /**
diff --git a/src/server/attr.cpp b/src/server/attr.cpp
index f1d6055..19eb524 100644
--- a/src/server/attr.cpp
+++ b/src/server/attr.cpp
@@ -73,17 +73,17 @@ void PyAttr::set_user_prop(vector<Tango::AttrProperty> &user_prop,
         else if (prop_name == "delta_t")
             def_prop.set_delta_t(prop_value);
         else if (prop_name == "abs_change")
-            def_prop.set_abs_change(prop_value);
+            def_prop.set_event_abs_change(prop_value);
         else if (prop_name == "rel_change")
-            def_prop.set_rel_change(prop_value);
+            def_prop.set_event_rel_change(prop_value);
         else if (prop_name == "period")
-            def_prop.set_period(prop_value);
+            def_prop.set_event_period(prop_value);
         else if (prop_name == "archive_abs_change")
-            def_prop.set_archive_abs_change(prop_value);
+            def_prop.set_archive_event_abs_change(prop_value);
         else if (prop_name == "archive_rel_change")
-            def_prop.set_archive_rel_change(prop_value);
+            def_prop.set_archive_event_rel_change(prop_value);
         else if (prop_name == "archive_period")
-            def_prop.set_archive_period(prop_value);
+            def_prop.set_archive_event_period(prop_value);
     }
 }
 
diff --git a/src/server/attr.h b/src/server/attr.h
index c0fbb8a..92a52bb 100644
--- a/src/server/attr.h
+++ b/src/server/attr.h
@@ -95,7 +95,7 @@ public:
         if (!_is_method(dev, read_name))
         {
             TangoSys_OMemStream o;
-            o << read_name << " method not found";
+            o << read_name << " method not found for " << att.get_name();
             Tango::Except::throw_exception("PyTango_ReadAttributeMethodNotFound",
                 o.str(), "PyTango::Attr::read");
         }
@@ -114,7 +114,7 @@ public:
         if (!_is_method(dev, write_name))
         {
             TangoSys_OMemStream o;
-            o << write_name << " method not found";
+            o << write_name << " method not found for " << att.get_name();
             Tango::Except::throw_exception("PyTango_WriteAttributeMethodNotFound",
                 o.str(), "PyTango::Attr::write");
         }
diff --git a/src/server/attribute.cpp b/src/server/attribute.cpp
index 06444c6..ef3d383 100644
--- a/src/server/attribute.cpp
+++ b/src/server/attribute.cpp
@@ -92,7 +92,7 @@ namespace PyAttribute
            I prefer this one since it decouples TangoC++ from PyTango and creating
            a scalar is not so expensive after all
         */
-        std::auto_ptr<TangoScalarType> cpp_val(new TangoScalarType);
+        unique_pointer<TangoScalarType> cpp_val(new TangoScalarType);
         
         from_py<tangoTypeConst>::convert(value, *cpp_val);
         att.set_value(cpp_val.release(), 1, 0, true);
@@ -181,7 +181,7 @@ namespace PyAttribute
            I prefer this one since it decouples TangoC++ from PyTango and creating
            a scalar is not so expensive after all
         */
-        std::auto_ptr<TangoScalarType> cpp_val(new TangoScalarType);
+        unique_pointer<TangoScalarType> cpp_val(new TangoScalarType);
         
         from_py<tangoTypeConst>::convert(value, *cpp_val);
         att.set_value_date_quality(cpp_val.release(), tv, quality, 1, 0, true);
@@ -330,12 +330,12 @@ namespace PyAttribute
                         fname + "()");
             } else {
                 if (quality)
-                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __set_value_date_quality_scalar, att, value, t, *quality);
+                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __set_value_date_quality_scalar, att, value, t, *quality);
                 else
-                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __set_value_scalar, att, value);
+                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __set_value_scalar, att, value);
             }
         } else {
-            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type,
+            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type,
                 __set_value_date_quality_array,
                     att, value, t, quality, x, y, fname, isImage);
         }
@@ -411,7 +411,63 @@ namespace PyAttribute
         att.get_properties_3(tg_attr_cfg);
         return to_py(tg_attr_cfg, attr_cfg);
     }
+
+    template<typename TangoScalarType>
+    inline void _get_properties_multi_attr_prop(Tango::Attribute &att, boost::python::object &multi_attr_prop)
+    {
+    	Tango::MultiAttrProp<TangoScalarType> tg_multi_attr_prop;
+    	att.get_properties(tg_multi_attr_prop);
+
+    	to_py(tg_multi_attr_prop,multi_attr_prop);
+    }
+
+#if TgLibVersNb < 80100 // _get_properties_multi_attr_prop<Tango::DevString>
+
+    // This is a hook dealing with a bug in Tango 8.0.5 related to AttrProp<Tango::DevString> specialisation
+    template<>
+    inline void _get_properties_multi_attr_prop<Tango::DevString>(Tango::Attribute &att, boost::python::object &multi_attr_prop)
+    {
+        Tango::AttributeConfig_3 tg_attr_cfg;
+        att.get_properties_3(tg_attr_cfg);
+
+        if(multi_attr_prop.ptr() == Py_None)
+        {
+            PYTANGO_MOD
+            multi_attr_prop = pytango.attr("MultiAttrProp")();
+        }
+
+        multi_attr_prop.attr("label") = tg_attr_cfg.label;
+        multi_attr_prop.attr("description") = tg_attr_cfg.description;
+        multi_attr_prop.attr("unit") = tg_attr_cfg.unit;
+        multi_attr_prop.attr("standard_unit") = tg_attr_cfg.standard_unit;
+        multi_attr_prop.attr("display_unit") = tg_attr_cfg.display_unit;
+        multi_attr_prop.attr("format") = tg_attr_cfg.format;
+        multi_attr_prop.attr("min_value") = tg_attr_cfg.min_value;
+        multi_attr_prop.attr("max_value") = tg_attr_cfg.max_value;
+        multi_attr_prop.attr("min_alarm") = tg_attr_cfg.att_alarm.min_alarm;
+        multi_attr_prop.attr("max_alarm") = tg_attr_cfg.att_alarm.max_alarm;
+        multi_attr_prop.attr("min_warning") = tg_attr_cfg.att_alarm.min_warning;
+        multi_attr_prop.attr("max_warning") = tg_attr_cfg.att_alarm.max_warning;
+        multi_attr_prop.attr("delta_t") = tg_attr_cfg.att_alarm.delta_t;
+        multi_attr_prop.attr("delta_val") = tg_attr_cfg.att_alarm.delta_val;
+        multi_attr_prop.attr("event_period") = tg_attr_cfg.event_prop.per_event.period;
+        multi_attr_prop.attr("archive_period") = tg_attr_cfg.event_prop.arch_event.period;
+        multi_attr_prop.attr("rel_change") = tg_attr_cfg.event_prop.ch_event.rel_change;
+        multi_attr_prop.attr("abs_change") = tg_attr_cfg.event_prop.ch_event.abs_change;
+        multi_attr_prop.attr("archive_rel_change") = tg_attr_cfg.event_prop.arch_event.rel_change;
+        multi_attr_prop.attr("archive_abs_change") = tg_attr_cfg.event_prop.arch_event.abs_change;
+    }
     
+#endif // _get_properties_multi_attr_prop<Tango::DevString>
+
+    inline boost::python::object get_properties_multi_attr_prop(Tango::Attribute &att,
+                                                boost::python::object &multi_attr_prop)
+    {
+    	long tangoTypeConst = att.get_data_type();
+		TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tangoTypeConst, _get_properties_multi_attr_prop, att, multi_attr_prop);
+		return multi_attr_prop;
+    }
+
     void set_properties(Tango::Attribute &att, boost::python::object &attr_cfg,
                         boost::python::object &dev)
     {
@@ -430,6 +486,35 @@ namespace PyAttribute
         att.set_properties(tg_attr_cfg, dev_ptr);
     }
 
+    template<typename TangoScalarType>
+    inline void _set_properties_multi_attr_prop(Tango::Attribute &att, boost::python::object &multi_attr_prop)
+    {
+    	Tango::MultiAttrProp<TangoScalarType> tg_multi_attr_prop;
+    	from_py_object(multi_attr_prop,tg_multi_attr_prop);
+    	att.set_properties(tg_multi_attr_prop);
+    }
+
+    void set_properties_multi_attr_prop(Tango::Attribute &att, boost::python::object &multi_attr_prop)
+    {
+    	long tangoTypeConst = att.get_data_type();
+		TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tangoTypeConst, _set_properties_multi_attr_prop, att, multi_attr_prop);
+    }
+
+    void set_upd_properties(Tango::Attribute &att, boost::python::object &attr_cfg)
+    {
+        Tango::AttributeConfig_3 tg_attr_cfg;
+        from_py_object(attr_cfg, tg_attr_cfg);
+        att.set_upd_properties(tg_attr_cfg);
+    }
+
+    void set_upd_properties(Tango::Attribute &att, boost::python::object &attr_cfg, boost::python::object &dev_name)
+    {
+        Tango::AttributeConfig_3 tg_attr_cfg;
+        from_py_object(attr_cfg, tg_attr_cfg);
+        string tg_dev_name = boost::python::extract<string>(dev_name);
+        att.set_upd_properties(tg_attr_cfg,tg_dev_name);
+    }
+
     inline void fire_change_event(Tango::Attribute &self)
     {
         self.fire_change_event();
@@ -451,6 +536,279 @@ namespace PyAttribute
                 o.str(),
                 "fire_change_event()");
     }
+    
+    // usually not necessary to rewrite but with direct declaration the compiler
+    // gives an error. It seems to be because the tango method definition is not
+    // in the header file.
+    inline bool is_polled(Tango::Attribute &self)
+    {
+        return self.is_polled();
+    }
+
+
+    template<typename TangoScalarType>
+    inline void _set_min_alarm(Tango::Attribute &self, boost::python::object value)
+    {
+		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+		self.set_min_alarm(c_value);
+    }
+
+#if TgLibVersNb < 80100 // set_min_alarm
+
+    template<>
+    inline void _set_min_alarm<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
+    {
+    	string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
+    	Tango::Except::throw_exception((const char *)"API_MethodArgument",
+    				  (const char *)err_msg.c_str(),
+    				  (const char *)"Attribute::set_min_alarm()");
+    }
+
+#endif // set_min_alarm
+
+    inline void set_min_alarm(Tango::Attribute &self, boost::python::object value)
+    {
+        bopy::extract<string> value_convert(value);
+        
+    	if (value_convert.check())
+    	{
+			self.set_min_alarm(value_convert());
+    	}
+    	else
+    	{
+			long tangoTypeConst = self.get_data_type();
+			// TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
+			// for one of the forbidden attribute data types; code dependent on Tango C++ implementation
+			if(tangoTypeConst == Tango::DEV_STRING || tangoTypeConst == Tango::DEV_BOOLEAN || tangoTypeConst == Tango::DEV_STATE)
+				tangoTypeConst = Tango::DEV_DOUBLE;
+			else if(tangoTypeConst == Tango::DEV_ENCODED)
+				tangoTypeConst = Tango::DEV_UCHAR;
+
+			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tangoTypeConst, _set_min_alarm, self, value);
+    	}
+    }
+
+
+    template<typename TangoScalarType>
+    inline void _set_max_alarm(Tango::Attribute &self, boost::python::object value)
+    {
+		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+		self.set_max_alarm(c_value);
+    }
+
+#if TgLibVersNb < 80100 // set_max_alarm
+
+    template<>
+    inline void _set_max_alarm<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
+    {
+    	string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
+    	Tango::Except::throw_exception((const char *)"API_MethodArgument",
+    				  (const char *)err_msg.c_str(),
+    				  (const char *)"Attribute::set_max_alarm()");
+    }
+
+#endif // set_max_alarm
+
+    inline void set_max_alarm(Tango::Attribute &self, boost::python::object value)
+    {
+        bopy::extract<string> value_convert(value);
+        
+    	if (value_convert.check())
+    	{
+			self.set_max_alarm(value_convert());
+    	}
+    	else
+    	{
+			long tangoTypeConst = self.get_data_type();
+			// TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
+			// for one of the forbidden attribute data types; code dependent on Tango C++ implementation
+			if(tangoTypeConst == Tango::DEV_STRING || tangoTypeConst == Tango::DEV_BOOLEAN || tangoTypeConst == Tango::DEV_STATE)
+				tangoTypeConst = Tango::DEV_DOUBLE;
+			else if(tangoTypeConst == Tango::DEV_ENCODED)
+				tangoTypeConst = Tango::DEV_UCHAR;
+
+			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tangoTypeConst, _set_max_alarm, self, value);
+    	}
+    }
+
+
+    template<typename TangoScalarType>
+    inline void _set_min_warning(Tango::Attribute &self, boost::python::object value)
+    {
+		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+		self.set_min_warning(c_value);
+    }
+
+#if TgLibVersNb < 80100 // set_min_warning
+
+    template<>
+    inline void _set_min_warning<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
+    {
+    	string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
+    	Tango::Except::throw_exception((const char *)"API_MethodArgument",
+    				  (const char *)err_msg.c_str(),
+    				  (const char *)"Attribute::set_min_warning()");
+    }
+
+#endif // set_min_warning
+
+    inline void set_min_warning(Tango::Attribute &self, boost::python::object value)
+    {
+        bopy::extract<string> value_convert(value);
+        
+    	if (value_convert.check())
+    	{
+			self.set_min_warning(value_convert());
+    	}
+    	else
+    	{
+			long tangoTypeConst = self.get_data_type();
+			// TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
+			// for one of the forbidden attribute data types; code dependent on Tango C++ implementation
+			if(tangoTypeConst == Tango::DEV_STRING || tangoTypeConst == Tango::DEV_BOOLEAN || tangoTypeConst == Tango::DEV_STATE)
+				tangoTypeConst = Tango::DEV_DOUBLE;
+			else if(tangoTypeConst == Tango::DEV_ENCODED)
+				tangoTypeConst = Tango::DEV_UCHAR;
+
+			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tangoTypeConst, _set_min_warning, self, value);
+    	}
+    }
+
+
+    template<typename TangoScalarType>
+    inline void _set_max_warning(Tango::Attribute &self, boost::python::object value)
+    {
+		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+		self.set_max_warning(c_value);
+    }
+
+#if TgLibVersNb < 80100 // set_max_warning
+
+    template<>
+    inline void _set_max_warning<Tango::DevEncoded>(Tango::Attribute &self, boost::python::object value)
+    {
+    	string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
+    	Tango::Except::throw_exception((const char *)"API_MethodArgument",
+    				  (const char *)err_msg.c_str(),
+    				  (const char *)"Attribute::set_max_warning()");
+    }
+
+#endif // set_max_warning
+
+    inline void set_max_warning(Tango::Attribute &self, boost::python::object value)
+    {
+        bopy::extract<string> value_convert(value);
+        
+    	if (value_convert.check())
+    	{
+			self.set_max_warning(value_convert());
+    	}
+    	else
+    	{
+			long tangoTypeConst = self.get_data_type();
+			// TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
+			// for one of the forbidden attribute data types; code dependent on Tango C++ implementation
+			if(tangoTypeConst == Tango::DEV_STRING || tangoTypeConst == Tango::DEV_BOOLEAN || tangoTypeConst == Tango::DEV_STATE)
+				tangoTypeConst = Tango::DEV_DOUBLE;
+			else if(tangoTypeConst == Tango::DEV_ENCODED)
+				tangoTypeConst = Tango::DEV_UCHAR;
+
+			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tangoTypeConst, _set_max_warning, self, value);
+    	}
+    }
+
+    template<long tangoTypeConst>
+    PyObject* __get_min_alarm(Tango::Attribute &att)
+    {
+        typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+
+        TangoScalarType tg_val;
+        att.get_min_alarm(tg_val);
+        boost::python::object py_value(tg_val);
+
+        return boost::python::incref(py_value.ptr());
+    }
+
+    PyObject *get_min_alarm(Tango::Attribute &att)
+    {
+        long tangoTypeConst = att.get_data_type();
+
+		if(tangoTypeConst == Tango::DEV_ENCODED)
+			tangoTypeConst = Tango::DEV_UCHAR;
+
+        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tangoTypeConst, return __get_min_alarm, att);
+        return 0;
+    }
+
+    template<long tangoTypeConst>
+    PyObject* __get_max_alarm(Tango::Attribute &att)
+    {
+        typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+
+        TangoScalarType tg_val;
+        att.get_max_alarm(tg_val);
+        boost::python::object py_value(tg_val);
+
+        return boost::python::incref(py_value.ptr());
+    }
+
+    PyObject *get_max_alarm(Tango::Attribute &att)
+    {
+        long tangoTypeConst = att.get_data_type();
+
+		if(tangoTypeConst == Tango::DEV_ENCODED)
+			tangoTypeConst = Tango::DEV_UCHAR;
+
+        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tangoTypeConst, return __get_max_alarm, att);
+        return 0;
+    }
+
+    template<long tangoTypeConst>
+    PyObject* __get_min_warning(Tango::Attribute &att)
+    {
+        typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+
+        TangoScalarType tg_val;
+        att.get_min_warning(tg_val);
+        boost::python::object py_value(tg_val);
+
+        return boost::python::incref(py_value.ptr());
+    }
+
+    PyObject *get_min_warning(Tango::Attribute &att)
+    {
+        long tangoTypeConst = att.get_data_type();
+
+		if(tangoTypeConst == Tango::DEV_ENCODED)
+			tangoTypeConst = Tango::DEV_UCHAR;
+
+        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tangoTypeConst, return __get_min_warning, att);
+        return 0;
+    }
+
+    template<long tangoTypeConst>
+    PyObject* __get_max_warning(Tango::Attribute &att)
+    {
+        typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+
+        TangoScalarType tg_val;
+        att.get_max_warning(tg_val);
+        boost::python::object py_value(tg_val);
+
+        return boost::python::incref(py_value.ptr());
+    }
+
+    PyObject *get_max_warning(Tango::Attribute &att)
+    {
+        long tangoTypeConst = att.get_data_type();
+
+		if(tangoTypeConst == Tango::DEV_ENCODED)
+			tangoTypeConst = Tango::DEV_UCHAR;
+
+        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tangoTypeConst, return __get_max_warning, att);
+        return 0;
+    }
+
 };
 
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(set_quality_overloads,
@@ -480,8 +838,7 @@ void export_attribute()
         .def("is_min_warning", &Tango::Attribute::is_min_warning)
         .def("is_max_warning", &Tango::Attribute::is_max_warning)
         .def("is_rds_alarm", &Tango::Attribute::is_rds_alarm)
-        //TODO .def("is_alarmed", &Tango::Attribute::is_alarmed)
-        .def("is_polled", &Tango::Attribute::is_polled)
+        .def("is_polled", &PyAttribute::is_polled)
         .def("check_alarm", &Tango::Attribute::check_alarm)
         .def("get_writable", &Tango::Attribute::get_writable)
         .def("get_name", &Tango::Attribute::get_name,
@@ -511,7 +868,25 @@ void export_attribute()
         .def("get_polling_period", &Tango::Attribute::get_polling_period)
         .def("set_attr_serial_model", &Tango::Attribute::set_attr_serial_model)
         .def("get_attr_serial_model", &Tango::Attribute::get_attr_serial_model)
-        
+
+        .def("set_min_alarm", &PyAttribute::set_min_alarm)
+        .def("set_max_alarm", &PyAttribute::set_max_alarm)
+        .def("set_min_warning", &PyAttribute::set_min_warning)
+        .def("set_max_warning", &PyAttribute::set_max_warning)
+
+        .def("get_min_alarm",
+			(PyObject* (*) (Tango::Attribute &))
+			&PyAttribute::get_min_alarm)
+        .def("get_max_alarm",
+			(PyObject* (*) (Tango::Attribute &))
+			&PyAttribute::get_max_alarm)
+        .def("get_min_warning",
+			(PyObject* (*) (Tango::Attribute &))
+			&PyAttribute::get_min_warning)
+        .def("get_max_warning",
+			(PyObject* (*) (Tango::Attribute &))
+			&PyAttribute::get_max_warning)
+
         .def("set_value",
             (void (*) (Tango::Attribute &, boost::python::object &))
             &PyAttribute::set_value)
@@ -556,10 +931,20 @@ void export_attribute()
         .def("_get_properties", &PyAttribute::get_properties)
         .def("_get_properties_2", &PyAttribute::get_properties_2)
         .def("_get_properties_3", &PyAttribute::get_properties_3)
+        .def("_get_properties_multi_attr_prop", &PyAttribute::get_properties_multi_attr_prop)
         
         .def("_set_properties", &PyAttribute::set_properties)
         .def("_set_properties_3", &PyAttribute::set_properties_3)
+        .def("_set_properties_multi_attr_prop", &PyAttribute::set_properties_multi_attr_prop)
         
+        .def("set_upd_properties",
+			(void (*) (Tango::Attribute &, boost::python::object &))
+			&PyAttribute::set_upd_properties)
+
+        .def("set_upd_properties",
+			(void (*) (Tango::Attribute &, boost::python::object &, boost::python::object &))
+			&PyAttribute::set_upd_properties)
+
         .def("fire_change_event",
             (void (*) (Tango::Attribute &))
             &PyAttribute::fire_change_event)
diff --git a/src/server/attribute.h b/src/server/attribute.h
index 0e0f0aa..24e3bce 100644
--- a/src/server/attribute.h
+++ b/src/server/attribute.h
@@ -60,11 +60,16 @@ namespace PyAttribute
     boost::python::object get_properties_3(Tango::Attribute &,
                                            boost::python::object &);
 
+    boost::python::object get_properties_multi_attr_prop(Tango::Attribute &,
+                                                    boost::python::object &);
+
     void set_properties(Tango::Attribute &, boost::python::object &,
                         boost::python::object &);
     
     void set_properties_3(Tango::Attribute &, boost::python::object &,
                           boost::python::object &);
+
+    void set_properties_multi_attr_prop(Tango::Attribute &, boost::python::object &);
 };
 
 
diff --git a/src/server/command.cpp b/src/server/command.cpp
index 069d788..9c3e79d 100644
--- a/src/server/command.cpp
+++ b/src/server/command.cpp
@@ -123,6 +123,24 @@ void insert_scalar<Tango::DEV_BOOLEAN>(boost::python::object &o, CORBA::Any &any
     any <<= any_value;
 }
 
+template<>
+void insert_scalar<Tango::DEV_ENCODED>(boost::python::object &o, CORBA::Any &any)
+{
+    bopy::object p0 = o[0];
+    bopy::object p1 = o[1];
+
+    const char* encoded_format = bopy::extract<const char *> (p0.ptr());
+    const char* encoded_data = bopy::extract<const char *> (p1.ptr());
+    
+    CORBA::ULong nb = bopy::len(p1);
+    Tango::DevVarCharArray arr(nb, nb, (CORBA::Octet*)encoded_data, false);
+    Tango::DevEncoded *data = new Tango::DevEncoded;
+    data->encoded_format = CORBA::string_dup(encoded_format);
+    data->encoded_data = arr;
+
+    any <<= data;
+}
+
 template<long tangoArrayTypeConst>
 void insert_array(boost::python::object &o, CORBA::Any &any)
 {   
@@ -164,6 +182,21 @@ template<>
 void extract_scalar<Tango::DEV_VOID>(const CORBA::Any &any, boost::python::object &o)
 {}
 
+template<>
+void extract_scalar<Tango::DEV_ENCODED>(const CORBA::Any &any, boost::python::object &o)
+{
+    Tango::DevEncoded* data;
+
+    if ((any >>= data) == false)
+        throw_bad_type(Tango::CmdArgTypeName[Tango::DEV_ENCODED]);
+    
+    bopy::str encoded_format(data[0].encoded_format);
+    bopy::str encoded_data((const char*)data[0].encoded_data.get_buffer(),
+                           data[0].encoded_data.length());
+    
+    o = boost::python::make_tuple(encoded_format, encoded_data);
+}
+
 #ifndef DISABLE_PYTANGO_NUMPY
 /// This callback is run to delete Tango::DevVarXArray* objects.
 /// It is called by python. The array was associated with an attribute
@@ -172,14 +205,24 @@ void extract_scalar<Tango::DEV_VOID>(const CORBA::Any &any, boost::python::objec
 /// @param type_ The type of the array objects. We need it to convert ptr_
 ///              to the proper type before deleting it.
 ///              ex: Tango::DEVVAR_SHORTARRAY.
-static void dev_var_x_array_deleter__(void * ptr_, void *type_)
-{
-    long type = reinterpret_cast<long>(type_);
-
-    TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(type,
-        delete static_cast<TANGO_const2type(tangoTypeConst)*>(ptr_);
-    );
-}
+#    ifdef PYCAPSULE_OLD
+         template<long type>
+         static void dev_var_x_array_deleter__(void * ptr_)
+         {
+             TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_ID(type,
+                 delete static_cast<TANGO_const2type(tangoTypeConst)*>(ptr_);
+             );
+         }
+#    else
+         template<long type>
+         static void dev_var_x_array_deleter__(PyObject* obj)
+         {
+             void * ptr_ = PyCapsule_GetPointer(obj, NULL);
+             TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_ID(type,
+                 delete static_cast<TANGO_const2type(tangoTypeConst)*>(ptr_);
+             );
+         }
+#endif
 #endif
 
 template<long tangoArrayTypeConst>
@@ -206,10 +249,10 @@ void extract_array(const CORBA::Any &any, boost::python::object &py_result)
       // PyCObject is intended for that kind of things. It's seen as a
       // black box object from python. We assign him a function to be called
       // when it is deleted -> the function deletes de data.
-      PyObject* guard = PyCObject_FromVoidPtrAndDesc(
+      PyObject* guard = PyCapsule_New(
               static_cast<void*>(copy_ptr),
-              reinterpret_cast<void*>(tangoArrayTypeConst),
-              dev_var_x_array_deleter__);
+              NULL,
+              dev_var_x_array_deleter__<tangoArrayTypeConst>);
       if (!guard ) {
           delete copy_ptr;
           throw_error_already_set();
@@ -232,7 +275,7 @@ CORBA::Any *PyCmd::execute(Tango::DeviceImpl *dev, const CORBA::Any &param_any)
         // So, the result is that param_py = param_any.
         // It is done with some template magic.
         boost::python::object param_py;
-        TANGO_DO_ON_DEVICE_DATA_TYPE(in_type, 
+        TANGO_DO_ON_DEVICE_DATA_TYPE_ID(in_type,
             extract_scalar<tangoTypeConst>(param_any, param_py);
         , 
             extract_array<tangoTypeConst>(param_any, param_py);
@@ -252,10 +295,10 @@ CORBA::Any *PyCmd::execute(Tango::DeviceImpl *dev, const CORBA::Any &param_any)
         
         CORBA::Any *ret_any;
         allocate_any(ret_any);
-        std::auto_ptr<CORBA::Any> ret_any_guard(ret_any);
+        unique_pointer<CORBA::Any> ret_any_guard(ret_any);
 
         // It does: ret_any = ret_py_obj
-        TANGO_DO_ON_DEVICE_DATA_TYPE(out_type, 
+        TANGO_DO_ON_DEVICE_DATA_TYPE_ID(out_type,
             insert_scalar<tangoTypeConst>(ret_py_obj, *ret_any);
         ,
             insert_array<tangoTypeConst>(ret_py_obj, *ret_any);
diff --git a/src/server/device_class.cpp b/src/server/device_class.cpp
index 4af89ba..7c203b9 100644
--- a/src/server/device_class.cpp
+++ b/src/server/device_class.cpp
@@ -267,7 +267,23 @@ namespace PyDeviceClass
         }
         return py_dev_list;
     }
-    
+
+    object get_command_list(CppDeviceClass &self)
+    {
+        boost::python::list py_cmd_list;
+        vector<Tango::Command *> cmd_list = self.get_command_list();
+        for(vector<Tango::Command *>::iterator it = cmd_list.begin(); it != cmd_list.end(); ++it)
+        {
+            object py_value = object(
+                        handle<>(
+                            to_python_indirect<
+                                Tango::Command*,
+                                detail::make_reference_holder>()(*it)));
+            py_cmd_list.append(py_value);
+        }
+        return py_cmd_list;
+    }
+        
     /*
     void add_device(CppDeviceClass &self, auto_ptr<Tango::DeviceImpl> dev)
     {
@@ -336,6 +352,9 @@ void export_device_class()
         .def("get_cvs_location",&Tango::DeviceClass::get_cvs_location,
             return_value_policy<copy_non_const_reference>())
         .def("get_device_list",&PyDeviceClass::get_device_list)
+        .def("get_command_list",&PyDeviceClass::get_device_list)
+        .def("get_cmd_by_name",&Tango::DeviceClass::get_cmd_by_name,
+            return_internal_reference<>())
         .def("set_type",
             (void (Tango::DeviceClass::*) (const char *))
             &Tango::DeviceClass::set_type)
diff --git a/src/server/device_impl.cpp b/src/server/device_impl.cpp
index 911f20a..16bd950 100644
--- a/src/server/device_impl.cpp
+++ b/src/server/device_impl.cpp
@@ -86,11 +86,14 @@ using namespace boost::python;
     __AUX_CATCH_PY_EXCEPTION \
     __AUX_CATCH_EXCEPTION(name)
 
+// we don't use extract<> from boost bellow to get attribute name because it is
+// considerably slow
 #define SAFE_PUSH(dev, attr, attr_name) \
-    char *__att_name_ptr = PyString_AsString(attr_name.ptr()); \
+    std::string __att_name; \
+    from_str_to_char(attr_name.ptr(), __att_name); \
     AutoPythonAllowThreads python_guard_ptr; \
     Tango::AutoTangoMonitor tango_guard(&dev); \
-    Tango::Attribute & attr = dev.get_device_attr()->get_attr_by_name(__att_name_ptr); \
+    Tango::Attribute & attr = dev.get_device_attr()->get_attr_by_name(__att_name.c_str()); \
     python_guard_ptr.giveup();
 
 #define SAFE_PUSH_CHANGE_EVENT(dev, attr_name, data) \
@@ -583,10 +586,11 @@ namespace PyDeviceImpl
         self.add_attribute(attr_ptr);
     }
 
-    void remove_attribute(Tango::DeviceImpl &self, const char *att_name)
+    void remove_attribute(Tango::DeviceImpl &self, const char *att_name,
+                          bool clean_db = true)
     {
         string str(att_name);
-        self.remove_attribute(str, false);
+        self.remove_attribute(str, false, clean_db);
     }
 
     inline void debug(Tango::DeviceImpl &self, const string &msg)
@@ -634,6 +638,54 @@ namespace PyDeviceImpl
         from_py_object(py_attr_conf_list, attr_conf_list);
         self.set_attribute_config(attr_conf_list);
     }
+    
+    bool is_attribute_polled(Tango::DeviceImpl &self, const std::string &att_name)
+    {
+        DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+        return self_w->_is_attribute_polled(att_name);
+    }
+
+    bool is_command_polled(Tango::DeviceImpl &self, const std::string &cmd_name)
+    {
+        DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+        return self_w->_is_command_polled(cmd_name);
+    }
+
+    int get_attribute_poll_period(Tango::DeviceImpl &self, const std::string &att_name)
+    {
+        DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+        return self_w->_get_attribute_poll_period(att_name);
+    }
+
+    int get_command_poll_period(Tango::DeviceImpl &self, const std::string &cmd_name)
+    {
+        DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+        return self_w->_get_command_poll_period(cmd_name);
+    }
+
+    void poll_attribute(Tango::DeviceImpl &self, const std::string &att_name, int period)
+    {
+        DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+        self_w->_poll_attribute(att_name, period);
+    }
+
+    void poll_command(Tango::DeviceImpl &self, const std::string &cmd_name, int period)
+    {
+        DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+        self_w->_poll_command(cmd_name, period);
+    }
+
+    void stop_poll_attribute(Tango::DeviceImpl &self, const std::string &att_name)
+    {
+        DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+        self_w->_stop_poll_attribute(att_name);
+    }
+
+    void stop_poll_command(Tango::DeviceImpl &self, const std::string &cmd_name)
+    {
+        DeviceImplWrap *self_w = (DeviceImplWrap*)(&self);
+        self_w->_stop_poll_command(cmd_name);
+    }
 }
 
 DeviceImplWrap::DeviceImplWrap(PyObject *self, CppDeviceClass *cl,
@@ -658,6 +710,48 @@ void DeviceImplWrap::init_device()
     this->get_override("init_device")();
 }
 
+bool DeviceImplWrap::_is_attribute_polled(const std::string &att_name)
+{
+    return this->is_attribute_polled(att_name);
+}
+
+bool DeviceImplWrap::_is_command_polled(const std::string &cmd_name)
+{
+    return this->is_command_polled(cmd_name);
+}
+
+int DeviceImplWrap::_get_attribute_poll_period(const std::string &att_name)
+{
+    return this->get_attribute_poll_period(att_name);
+}
+
+int DeviceImplWrap::_get_command_poll_period(const std::string &cmd_name)
+{
+    return this->get_command_poll_period(cmd_name);
+}
+
+void DeviceImplWrap::_poll_attribute(const std::string &att_name, int period)
+{
+    this->poll_attribute(att_name, period);
+}
+
+void DeviceImplWrap::_poll_command(const std::string &cmd_name, int period)
+{
+    this->poll_command(cmd_name, period);
+}
+
+void DeviceImplWrap::_stop_poll_attribute(const std::string &att_name)
+{
+    this->stop_poll_attribute(att_name);
+}
+
+void DeviceImplWrap::_stop_poll_command(const std::string &cmd_name)
+{
+    this->stop_poll_command(cmd_name);
+}
+
+
+
 Device_2ImplWrap::Device_2ImplWrap(PyObject *self, CppDeviceClass *cl,
                                    std::string &st)
     :Tango::Device_2Impl(cl,st),m_self(self)
@@ -1051,7 +1145,9 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(set_archive_event_overload,
 BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(push_data_ready_event_overload,
                                        Tango::DeviceImpl::push_data_ready_event, 1, 2)
 
-
+BOOST_PYTHON_FUNCTION_OVERLOADS(remove_attribute_overload,
+                                PyDeviceImpl::remove_attribute, 2, 3)
+                                       
 void export_device_impl()
 {
  
@@ -1100,12 +1196,19 @@ void export_device_impl()
             &Tango::DeviceImpl::set_archive_event,
             set_archive_event_overload())
         .def("_add_attribute", &PyDeviceImpl::add_attribute)
-        .def("_remove_attribute", &PyDeviceImpl::remove_attribute)
+        .def("_remove_attribute", &PyDeviceImpl::remove_attribute,
+            remove_attribute_overload())
         //@TODO .def("get_device_class")
-        //@TODO .def("get_device_attr")
         //@TODO .def("get_db_device")
-        
-        
+        .def("is_attribute_polled", &PyDeviceImpl::is_attribute_polled)
+        .def("is_command_polled", &PyDeviceImpl::is_command_polled)
+        .def("get_attribute_poll_period", &PyDeviceImpl::get_attribute_poll_period)
+        .def("get_command_poll_period", &PyDeviceImpl::get_command_poll_period)
+        .def("poll_attribute", &PyDeviceImpl::poll_attribute)
+        .def("poll_command", &PyDeviceImpl::poll_command)
+        .def("stop_poll_attribute", &PyDeviceImpl::stop_poll_attribute)
+        .def("stop_poll_command", &PyDeviceImpl::stop_poll_command)
+                        
         .def("get_exported_flag", &Tango::DeviceImpl::get_exported_flag)
         .def("get_poll_ring_depth", &Tango::DeviceImpl::get_poll_ring_depth)
         .def("get_poll_old_factor", &Tango::DeviceImpl::get_poll_old_factor)
diff --git a/src/server/device_impl.h b/src/server/device_impl.h
index 91d4a5e..6ac340d 100644
--- a/src/server/device_impl.h
+++ b/src/server/device_impl.h
@@ -73,6 +73,15 @@ public:
      * Invokes the actual init_device
      */
     void init_device();
+    
+    bool _is_attribute_polled(const std::string &att_name);
+    bool _is_command_polled(const std::string &cmd_name);
+    int _get_attribute_poll_period(const std::string &att_name);
+    int _get_command_poll_period(const std::string &cmd_name);
+    void _poll_attribute(const std::string &att_name, int period);
+    void _poll_command(const std::string &cmd_name, int period);
+    void _stop_poll_attribute(const std::string &att_name);
+    void _stop_poll_command(const std::string &cmd_name);
 };
 
 /**
@@ -172,21 +181,6 @@ public:
     virtual ~Device_3ImplWrap();
     
     /**
-     * A wrapper around the add_attribute in order to process some
-     * internal information
-     *
-     * @param att the attribute reference containning information about
-     *            the new attribute to be added
-     */
-    void _add_attribute(const Tango::Attr &att);
-
-    /**
-     * Wrapper around the remove_attribute in order to simplify
-     * string & to const string & conversion and default parameters
-     */
-    void _remove_attribute(const char *att_name);
-
-    /**
      * Necessary init_device implementation to call python
      */
     virtual void init_device();
@@ -314,21 +308,6 @@ public:
     virtual ~Device_4ImplWrap();
 
     /**
-     * A wrapper around the add_attribute in order to process some
-     * internal information
-     *
-     * @param att the attribute reference containning information about
-     *            the new attribute to be added
-     */
-    void _add_attribute(const Tango::Attr &att);
-
-    /**
-     * Wrapper around the remove_attribute in order to simplify
-     * string & to const string & conversion and default parameters
-     */
-    void _remove_attribute(const char *att_name);
-
-    /**
      * Necessary init_device implementation to call python
      */
     virtual void init_device();
diff --git a/src/server/encoded_attribute.cpp b/src/server/encoded_attribute.cpp
index 62708ea..4a44179 100644
--- a/src/server/encoded_attribute.cpp
+++ b/src/server/encoded_attribute.cpp
@@ -34,30 +34,43 @@ const int i = 1;
 namespace PyEncodedAttribute
 {
 
-	/// This callback is run to delete char* objects.
+    /// This callback is run to delete char* objects.
     /// It is called by python. The array was associated with an attribute
     /// value object that is not being used anymore.
     /// @param ptr_ The array object.
     /// @param type_ The type of data. We don't need it for now
-
-    static void __ptr_deleter(void * ptr_, void *type_)
-    {
-        long t = reinterpret_cast<long>(type_);
-        if (1 == t)
-            delete [] (static_cast<unsigned char*>(ptr_));
-        else if (2 == t)
-            delete [] (static_cast<unsigned short*>(ptr_));
-        else if (4 == t)
-			delete [] (static_cast<Tango::DevULong*>(ptr_));
-    }
+#    ifdef PYCAPSULE_OLD
+         template<long type>
+         static void __ptr_deleter(void * ptr_)
+         {
+             if (1 == type)
+                 delete [] (static_cast<unsigned char*>(ptr_));
+             else if (2 == type)
+                 delete [] (static_cast<unsigned short*>(ptr_));
+             else if (4 == type)
+                 delete [] (static_cast<Tango::DevULong*>(ptr_));
+         }
+#    else
+         template<long type>
+         static void __ptr_deleter(PyObject* obj)
+         {
+             void * ptr_ = PyCapsule_GetPointer(obj, NULL);
+             if (1 == type)
+                 delete [] (static_cast<unsigned char*>(ptr_));
+             else if (2 == type)
+                 delete [] (static_cast<unsigned short*>(ptr_));
+             else if (4 == type)
+                 delete [] (static_cast<Tango::DevULong*>(ptr_));
+         }
+#    endif
     
     void encode_gray8(Tango::EncodedAttribute &self, object py_value, int w, int h)
     {
         PyObject *py_value_ptr = py_value.ptr();
         unsigned char *buffer = NULL;
-        if (PyString_Check(py_value_ptr))
+        if (PyBytes_Check(py_value_ptr))
         {
-            buffer = reinterpret_cast<unsigned char*>(PyString_AsString(py_value_ptr));
+            buffer = reinterpret_cast<unsigned char*>(PyBytes_AsString(py_value_ptr));
             self.encode_gray8(buffer, w, h);
             return;
         }
@@ -74,9 +87,9 @@ namespace PyEncodedAttribute
 #endif
         // It must be a py sequence
         // we are sure that w and h are given by python (see encoded_attribute.py)
-		const int length = w*h;
-	    unsigned char *raw_b = new unsigned char[length];
-		auto_ptr<unsigned char> b(raw_b);
+        const int length = w*h;
+        unsigned char *raw_b = new unsigned char[length];
+        unique_pointer<unsigned char> b(raw_b);
         buffer = raw_b;
         unsigned char *p = raw_b;
         int w_bytes = w;
@@ -93,16 +106,16 @@ namespace PyEncodedAttribute
                 boost::python::throw_error_already_set();
             }
             // The given object is a sequence of strings were each string is the entire row
-            if (PyString_Check(row))
+            if (PyBytes_Check(row))
             {
-                if (PyString_Size(row) != w_bytes)
+                if (PyBytes_Size(row) != w_bytes)
                 {
                     Py_DECREF(row);
                     PyErr_SetString(PyExc_TypeError,
                         "All sequences inside a sequence must have same size");
                     boost::python::throw_error_already_set();
                 }
-                memcpy(p, PyString_AsString(row), w_bytes);
+                memcpy(p, PyBytes_AsString(row), w_bytes);
                 p += w;
             }
             else
@@ -123,9 +136,9 @@ namespace PyEncodedAttribute
                         Py_DECREF(row);
                         boost::python::throw_error_already_set();
                     }
-                    if (PyString_Check(cell))
+                    if (PyBytes_Check(cell))
                     {
-                        if (PyString_Size(cell) != 1)
+                        if (PyBytes_Size(cell) != 1)
                         {
                             Py_DECREF(row);
                             Py_DECREF(cell);
@@ -133,10 +146,10 @@ namespace PyEncodedAttribute
                                 "All string items must have length one");
                             boost::python::throw_error_already_set();
                         }
-                        char byte = PyString_AsString(cell)[0];
+                        char byte = PyBytes_AsString(cell)[0];
                         *p = byte;
                     }
-                    else if (PyInt_Check(cell) || PyLong_Check(cell))
+                    else if (PyLong_Check(cell))
                     {
                         long byte = PyLong_AsLong(cell);
                         if (byte==-1 && PyErr_Occurred())
@@ -169,9 +182,9 @@ namespace PyEncodedAttribute
     {
         PyObject *py_value_ptr = py_value.ptr();
         unsigned char *buffer = NULL;
-        if (PyString_Check(py_value_ptr))
+        if (PyBytes_Check(py_value_ptr))
         {
-            buffer = reinterpret_cast<unsigned char*>(PyString_AsString(py_value_ptr));
+            buffer = reinterpret_cast<unsigned char*>(PyBytes_AsString(py_value_ptr));
             self.encode_jpeg_gray8(buffer, w, h, quality);
             return;
         }
@@ -188,10 +201,10 @@ namespace PyEncodedAttribute
 #endif
         // It must be a py sequence
         // we are sure that w and h are given by python (see encoded_attribute.py)
-		const int length = w*h;
+        const int length = w*h;
         unsigned char *raw_b = new unsigned char[length];
-        auto_ptr<unsigned char> b(raw_b);
-		buffer = raw_b;
+        unique_pointer<unsigned char> b(raw_b);
+        buffer = raw_b;
         unsigned char *p = raw_b;
         int w_bytes = w;
         for (long y=0; y<h; ++y)
@@ -207,16 +220,16 @@ namespace PyEncodedAttribute
                 boost::python::throw_error_already_set();
             }
             // The given object is a sequence of strings were each string is the entire row
-            if (PyString_Check(row))
+            if (PyBytes_Check(row))
             {
-                if (PyString_Size(row) != w_bytes)
+                if (PyBytes_Size(row) != w_bytes)
                 {
                     Py_DECREF(row);
                     PyErr_SetString(PyExc_TypeError,
                         "All sequences inside a sequence must have same size");
                     boost::python::throw_error_already_set();
                 }
-                memcpy(p, PyString_AsString(row), w_bytes);
+                memcpy(p, PyBytes_AsString(row), w_bytes);
                 p += w;
             }
             else
@@ -237,9 +250,9 @@ namespace PyEncodedAttribute
                         Py_DECREF(row);
                         boost::python::throw_error_already_set();
                     }
-                    if (PyString_Check(cell))
+                    if (PyBytes_Check(cell))
                     {
-                        if (PyString_Size(cell) != 1)
+                        if (PyBytes_Size(cell) != 1)
                         {
                             Py_DECREF(row);
                             Py_DECREF(cell);
@@ -247,10 +260,10 @@ namespace PyEncodedAttribute
                                 "All string items must have length one");
                             boost::python::throw_error_already_set();
                         }
-                        char byte = PyString_AsString(cell)[0];
+                        char byte = PyBytes_AsString(cell)[0];
                         *p = byte;
                     }
-                    else if (PyInt_Check(cell) || PyLong_Check(cell))
+                    else if (PyLong_Check(cell))
                     {
                         long byte = PyLong_AsLong(cell);
                         if (byte==-1 && PyErr_Occurred())
@@ -283,9 +296,9 @@ namespace PyEncodedAttribute
     {
         PyObject *py_value_ptr = py_value.ptr();
         unsigned short *buffer = NULL;
-        if (PyString_Check(py_value_ptr))
+        if (PyBytes_Check(py_value_ptr))
         {
-            buffer = reinterpret_cast<unsigned short*>(PyString_AsString(py_value_ptr));
+            buffer = reinterpret_cast<unsigned short*>(PyBytes_AsString(py_value_ptr));
             self.encode_gray16(buffer, w, h);
             return;
         }
@@ -302,10 +315,10 @@ namespace PyEncodedAttribute
 #endif
         // It must be a py sequence
         // we are sure that w and h are given by python (see encoded_attribute.py)
-		const int length = w*h;
+        const int length = w*h;
         unsigned short *raw_b = new unsigned short[length];
-        auto_ptr<unsigned short> b(raw_b);
-		buffer = raw_b;
+        unique_pointer<unsigned short> b(raw_b);
+        buffer = raw_b;
         unsigned short *p = raw_b;
         int w_bytes = 2*w;
         for (long y=0; y<h; ++y)
@@ -321,16 +334,16 @@ namespace PyEncodedAttribute
                 boost::python::throw_error_already_set();
             }
             // The given object is a sequence of strings were each string is the entire row
-            if (PyString_Check(row))
+            if (PyBytes_Check(row))
             {
-                if (PyString_Size(row) != w_bytes)
+                if (PyBytes_Size(row) != w_bytes)
                 {
                     Py_DECREF(row);
                     PyErr_SetString(PyExc_TypeError,
                         "All sequences inside a sequence must have same size");
                     boost::python::throw_error_already_set();
                 }
-                memcpy(p, PyString_AsString(row), w_bytes);
+                memcpy(p, PyBytes_AsString(row), w_bytes);
                 p += w;
             }
             else
@@ -351,9 +364,9 @@ namespace PyEncodedAttribute
                         Py_DECREF(row);
                         boost::python::throw_error_already_set();
                     }
-                    if (PyString_Check(cell))
+                    if (PyBytes_Check(cell))
                     {
-                        if (PyString_Size(cell) != 2)
+                        if (PyBytes_Size(cell) != 2)
                         {
                             Py_DECREF(row);
                             Py_DECREF(cell);
@@ -361,10 +374,10 @@ namespace PyEncodedAttribute
                                 "All string items must have length two");
                             boost::python::throw_error_already_set();
                         }
-                        unsigned short *word = reinterpret_cast<unsigned short *>(PyString_AsString(cell));
+                        unsigned short *word = reinterpret_cast<unsigned short *>(PyBytes_AsString(cell));
                         *p = *word;
                     }
-                    else if (PyInt_Check(cell) || PyLong_Check(cell))
+                    else if (PyLong_Check(cell))
                     {
                         unsigned short word = (unsigned short)PyLong_AsUnsignedLong(cell);
                         if (PyErr_Occurred())
@@ -396,9 +409,9 @@ namespace PyEncodedAttribute
     {
         PyObject *py_value_ptr = py_value.ptr();
         unsigned char *buffer = NULL;
-        if (PyString_Check(py_value_ptr))
+        if (PyBytes_Check(py_value_ptr))
         {
-            buffer = reinterpret_cast<unsigned char*>(PyString_AsString(py_value_ptr));
+            buffer = reinterpret_cast<unsigned char*>(PyBytes_AsString(py_value_ptr));
             self.encode_rgb24(buffer, w, h);
             return;
         }
@@ -412,10 +425,10 @@ namespace PyEncodedAttribute
 #endif
         // It must be a py sequence
         // we are sure that w and h are given by python (see encoded_attribute.py)
-		const int length = w*h;
+        const int length = w*h;
         unsigned char *raw_b = new unsigned char[length];
-        auto_ptr<unsigned char> b(raw_b);
-		buffer = raw_b;
+        unique_pointer<unsigned char> b(raw_b);
+        buffer = raw_b;
         unsigned char *p = raw_b;
         int w_bytes = 3*w;
         for (long y=0; y<h; ++y)
@@ -431,16 +444,16 @@ namespace PyEncodedAttribute
                 boost::python::throw_error_already_set();
             }
             // The given object is a sequence of strings were each string is the entire row
-            if (PyString_Check(row))
+            if (PyBytes_Check(row))
             {
-                if (PyString_Size(row) != w_bytes)
+                if (PyBytes_Size(row) != w_bytes)
                 {
                     Py_DECREF(row);
                     PyErr_SetString(PyExc_TypeError,
                         "All sequences inside a sequence must have same size");
                     boost::python::throw_error_already_set();
                 }
-                memcpy(p, PyString_AsString(row), w_bytes);
+                memcpy(p, PyBytes_AsString(row), w_bytes);
                 p += w;
             }
             else
@@ -461,9 +474,9 @@ namespace PyEncodedAttribute
                         Py_DECREF(row);
                         boost::python::throw_error_already_set();
                     }
-                    if (PyString_Check(cell))
+                    if (PyBytes_Check(cell))
                     {
-                        if (PyString_Size(cell) != 3)
+                        if (PyBytes_Size(cell) != 3)
                         {
                             Py_DECREF(row);
                             Py_DECREF(cell);
@@ -471,12 +484,12 @@ namespace PyEncodedAttribute
                                 "All string items must have length one");
                             boost::python::throw_error_already_set();
                         }
-                        char *byte = PyString_AsString(cell);
+                        char *byte = PyBytes_AsString(cell);
                         *p = *byte; p++; byte++;
                         *p = *byte; p++; byte++;
                         *p = *byte; p++;
                     }
-                    else if (PyInt_Check(cell) || PyLong_Check(cell))
+                    else if (PyLong_Check(cell))
                     {
                         long byte = PyLong_AsLong(cell);
                         if (byte==-1 && PyErr_Occurred())
@@ -510,9 +523,9 @@ namespace PyEncodedAttribute
     {
         PyObject *py_value_ptr = py_value.ptr();
         unsigned char *buffer = NULL;
-        if (PyString_Check(py_value_ptr))
+        if (PyBytes_Check(py_value_ptr))
         {
-            buffer = reinterpret_cast<unsigned char*>(PyString_AsString(py_value_ptr));
+            buffer = reinterpret_cast<unsigned char*>(PyBytes_AsString(py_value_ptr));
             self.encode_jpeg_rgb24(buffer, w, h, quality);
             return;
         }
@@ -528,7 +541,7 @@ namespace PyEncodedAttribute
         // we are sure that w and h are given by python (see encoded_attribute.py)
 		const int length = w*h;
         unsigned char *raw_b = new unsigned char[length];
-        auto_ptr<unsigned char> b(raw_b);
+        unique_pointer<unsigned char> b(raw_b);
 		buffer = raw_b;
         unsigned char *p = raw_b;
         int w_bytes = 3*w;
@@ -545,16 +558,16 @@ namespace PyEncodedAttribute
                 boost::python::throw_error_already_set();
             }
             // The given object is a sequence of strings were each string is the entire row
-            if (PyString_Check(row))
+            if (PyBytes_Check(row))
             {
-                if (PyString_Size(row) != w_bytes)
+                if (PyBytes_Size(row) != w_bytes)
                 {
                     Py_DECREF(row);
                     PyErr_SetString(PyExc_TypeError,
                         "All sequences inside a sequence must have same size");
                     boost::python::throw_error_already_set();
                 }
-                memcpy(p, PyString_AsString(row), w_bytes);
+                memcpy(p, PyBytes_AsString(row), w_bytes);
                 p += w;
             }
             else
@@ -575,9 +588,9 @@ namespace PyEncodedAttribute
                         Py_DECREF(row);
                         boost::python::throw_error_already_set();
                     }
-                    if (PyString_Check(cell))
+                    if (PyBytes_Check(cell))
                     {
-                        if (PyString_Size(cell) != 3)
+                        if (PyBytes_Size(cell) != 3)
                         {
                             Py_DECREF(row);
                             Py_DECREF(cell);
@@ -585,12 +598,12 @@ namespace PyEncodedAttribute
                                 "All string items must have length one");
                             boost::python::throw_error_already_set();
                         }
-                        char *byte = PyString_AsString(cell);
+                        char *byte = PyBytes_AsString(cell);
                         *p = *byte; p++; byte++;
                         *p = *byte; p++; byte++;
                         *p = *byte; p++;
                     }
-                    else if (PyInt_Check(cell) || PyLong_Check(cell))
+                    else if (PyLong_Check(cell))
                     {
                         long byte = PyLong_AsLong(cell);
                         if (byte==-1 && PyErr_Occurred())
@@ -624,9 +637,9 @@ namespace PyEncodedAttribute
     {
         PyObject *py_value_ptr = py_value.ptr();
         unsigned char *buffer = NULL;
-        if (PyString_Check(py_value_ptr))
+        if (PyBytes_Check(py_value_ptr))
         {
-            buffer = reinterpret_cast<unsigned char*>(PyString_AsString(py_value_ptr));
+            buffer = reinterpret_cast<unsigned char*>(PyBytes_AsString(py_value_ptr));
             self.encode_jpeg_rgb32(buffer, w, h, quality);
             return;
         }
@@ -642,7 +655,7 @@ namespace PyEncodedAttribute
         // we are sure that w and h are given by python (see encoded_attribute.py)
 		const int length = w*h;
         unsigned char *raw_b = new unsigned char[length];
-        auto_ptr<unsigned char> b(raw_b);
+        unique_pointer<unsigned char> b(raw_b);
 		buffer = raw_b;
         unsigned char *p = raw_b;
         int w_bytes = 4*w;
@@ -659,16 +672,16 @@ namespace PyEncodedAttribute
                 boost::python::throw_error_already_set();
             }
             // The given object is a sequence of strings were each string is the entire row
-            if (PyString_Check(row))
+            if (PyBytes_Check(row))
             {
-                if (PyString_Size(row) != w_bytes)
+                if (PyBytes_Size(row) != w_bytes)
                 {
                     Py_DECREF(row);
                     PyErr_SetString(PyExc_TypeError,
                         "All sequences inside a sequence must have same size");
                     boost::python::throw_error_already_set();
                 }
-                memcpy(p, PyString_AsString(row), w_bytes);
+                memcpy(p, PyBytes_AsString(row), w_bytes);
                 p += w;
             }
             else
@@ -689,9 +702,9 @@ namespace PyEncodedAttribute
                         Py_DECREF(row);
                         boost::python::throw_error_already_set();
                     }
-                    if (PyString_Check(cell))
+                    if (PyBytes_Check(cell))
                     {
-                        if (PyString_Size(cell) != 3)
+                        if (PyBytes_Size(cell) != 3)
                         {
                             Py_DECREF(row);
                             Py_DECREF(cell);
@@ -699,13 +712,13 @@ namespace PyEncodedAttribute
                                 "All string items must have length one");
                             boost::python::throw_error_already_set();
                         }
-                        char *byte = PyString_AsString(cell);
+                        char *byte = PyBytes_AsString(cell);
                         *p = *byte; p++; byte++;
                         *p = *byte; p++; byte++;
                         *p = *byte; p++; byte++;
                         *p = *byte; p++;
                     }
-                    else if (PyInt_Check(cell) || PyLong_Check(cell))
+                    else if (PyLong_Check(cell))
                     {
                         long byte = PyLong_AsLong(cell);
                         if (byte==-1 && PyErr_Occurred())
@@ -764,10 +777,10 @@ namespace PyEncodedAttribute
                 // PyCObject is intended for that kind of things. It's seen as a
                 // black box object from python. We assign him a function to be called
                 // when it is deleted -> the function deletes de data.
-                PyObject* guard = PyCObject_FromVoidPtrAndDesc(
-                    static_cast<void*>(ch_ptr),
-                    reinterpret_cast<void*>(1),
-                    __ptr_deleter);
+                PyObject* guard = PyCapsule_New(
+                        static_cast<void*>(ch_ptr),
+                        NULL,
+                        __ptr_deleter<1>);
                     
                 if (!guard)
                 {
@@ -789,7 +802,7 @@ namespace PyEncodedAttribute
                     throw_error_already_set();
                 }
                 size_t nb_bytes = width*height*sizeof(char);
-                PyObject *buffer_str = PyString_FromStringAndSize(ch_ptr, nb_bytes);
+                PyObject *buffer_str = PyBytes_FromStringAndSize(ch_ptr, nb_bytes);
                 if (!buffer_str)
                 {
                     Py_XDECREF(ret);
@@ -823,7 +836,7 @@ namespace PyEncodedAttribute
                     }
                     for (long x=0; x < width; ++x)
                     {
-                        PyTuple_SetItem(row, x, PyString_FromStringAndSize(ch_ptr + y*width+x, 1));
+                        PyTuple_SetItem(row, x, PyBytes_FromStringAndSize(ch_ptr + y*width+x, 1));
                     }
                     PyTuple_SetItem(ret, y, row);
                 }
@@ -831,7 +844,6 @@ namespace PyEncodedAttribute
                 delete [] buffer;
                 break;
             }
-            case PyTango::ExtractAsPyTango3:
             case PyTango::ExtractAsList:
             {
                 ret = PyList_New(height);
@@ -852,7 +864,7 @@ namespace PyEncodedAttribute
                     }
                     for (long x=0; x < width; ++x)
                     {
-                        PyList_SetItem(row, x, PyString_FromStringAndSize(ch_ptr + y*width+x, 1));
+                        PyList_SetItem(row, x, PyBytes_FromStringAndSize(ch_ptr + y*width+x, 1));
                     }
                     PyList_SetItem(ret, y, row);
                 }
@@ -899,10 +911,10 @@ namespace PyEncodedAttribute
                 // PyCObject is intended for that kind of things. It's seen as a
                 // black box object from python. We assign him a function to be called
                 // when it is deleted -> the function deletes de data.
-                PyObject* guard = PyCObject_FromVoidPtrAndDesc(
+                PyObject* guard = PyCapsule_New(
                     static_cast<void*>(ch_ptr),
-                    reinterpret_cast<void*>(2),
-                    __ptr_deleter);
+                    NULL,
+                    __ptr_deleter<2>);
                     
                 if (!guard)
                 {
@@ -925,7 +937,7 @@ namespace PyEncodedAttribute
                 }
                 size_t nb_bytes = width*height*sizeof(unsigned short);
                 
-                PyObject *buffer_str = PyString_FromStringAndSize(
+                PyObject *buffer_str = PyBytes_FromStringAndSize(
                     reinterpret_cast<char *>(ch_ptr), nb_bytes);
                 delete [] buffer;
                 
@@ -969,7 +981,6 @@ namespace PyEncodedAttribute
                 delete [] buffer;
                 break;
             }
-            case PyTango::ExtractAsPyTango3:
             case PyTango::ExtractAsList:
             {
                 ret = PyList_New(height);
@@ -1036,11 +1047,11 @@ namespace PyEncodedAttribute
                 // the last copy of numpy.ndarray() disappears.
                 // PyCObject is intended for that kind of things. It's seen as a
                 // black box object from python. We assign him a function to be called
-                PyObject* guard = PyCObject_FromVoidPtrAndDesc(
                 // when it is deleted -> the function deletes de data.
+                PyObject* guard = PyCapsule_New(
                     static_cast<void*>(ch_ptr),
-                    reinterpret_cast<void*>(2),
-                    __ptr_deleter);
+                    NULL,
+                    __ptr_deleter<4>);
                     
                 if (!guard)
                 {
@@ -1063,7 +1074,7 @@ namespace PyEncodedAttribute
                 }
                 size_t nb_bytes = width*height*4;
                 
-                PyObject *buffer_str = PyString_FromStringAndSize(
+                PyObject *buffer_str = PyBytes_FromStringAndSize(
                     reinterpret_cast<char *>(ch_ptr), nb_bytes);
                 delete [] buffer;
                 
@@ -1127,7 +1138,6 @@ namespace PyEncodedAttribute
                 delete [] buffer;
                 break;
             }
-            case PyTango::ExtractAsPyTango3:
             case PyTango::ExtractAsList:
             {
                 ret = PyList_New(height);
@@ -1209,4 +1219,4 @@ void export_encoded_attribute()
         .def("_decode_gray16", &PyEncodedAttribute::decode_gray16)
         .def("_decode_rgb32", &PyEncodedAttribute::decode_rgb32)
     ;
-}
\ No newline at end of file
+}
diff --git a/src/server/log4tango.cpp b/src/server/log4tango.cpp
index c7674d2..eb29b87 100644
--- a/src/server/log4tango.cpp
+++ b/src/server/log4tango.cpp
@@ -45,7 +45,9 @@ namespace PyLogging
         par.length(len);
         for(int i = 0; i < len; ++i)
         {
-            par[i] = CORBA::string_dup(PyString_AsString(PySequence_GetItem(obj_ptr, i)));
+            PyObject* item_ptr = PySequence_GetItem(obj_ptr, i);
+            str item = str(handle<>(item_ptr));
+            par[i] = CORBA::string_dup(extract<const char*>(item));
         }
         Tango::Logging::add_logging_target(&par);
     }
@@ -63,7 +65,9 @@ namespace PyLogging
         par.length(len);
         for(int i = 0; i < len; ++i)
         {
-            par[i] = CORBA::string_dup(PyString_AsString(PySequence_GetItem(obj_ptr, i)));
+            PyObject* item_ptr = PySequence_GetItem(obj_ptr, i);
+            str item = str(handle<>(item_ptr));
+            par[i] = CORBA::string_dup(extract<const char*>(item));
         }
         Tango::Logging::remove_logging_target(&par);
     }
diff --git a/src/server/tango_util.cpp b/src/server/tango_util.cpp
index 3469f7d..6639e27 100644
--- a/src/server/tango_util.cpp
+++ b/src/server/tango_util.cpp
@@ -29,83 +29,6 @@
 
 using namespace boost::python;
 
-#ifndef _TG_WINDOWS_
-#include <unistd.h>
-#include <signal.h>
-#include <dlfcn.h>
-#endif /* _TG_WINDOWS_ */
-
-typedef Tango::DeviceClass *(*Cpp_creator_ptr)(const char *);
-
-Tango::DeviceClass* create_cpp_class(const std::string& class_name,
-                                     const std::string& par_name)
-{
-    std::string lib_name = class_name;
-    std::string sym_name = "_create_" + class_name + "_class";
-    
-#ifdef _TG_WINDOWS_
-    HMODULE mod;
-
-    if ((mod = LoadLibrary(lib_name.c_str())) == NULL)
-    {
-           char *str = 0;
-        
-        DWORD l_err = GetLastError();
-            ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,
-                  l_err,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(char *)&str,0,NULL);
-
-        cerr << "Error: " << str << endl;
-
-        TangoSys_OMemStream o;
-        o << "Trying to load shared library " << lib_name
-          << " failed. It returns error: " << str << ends;
-        ::LocalFree((HLOCAL)str);
-
-        Tango::Except::throw_exception("API_ClassNotFound", o.str(),
-                                       "DServer::create_cpp_class");
-    }
-    FARPROC proc;
-    
-    if ((proc = GetProcAddress(mod,sym_name.c_str())) == NULL)
-    {
-        TangoSys_OMemStream o;
-        o << "Class " << class_name << " does not have the C creator function "
-             "(_create_<Class name>_class)" << ends;
-
-        Tango::Except::throw_exception("API_ClassNotFound", o.str(),
-                                       "DServer::create_cpp_class");
-    }
-    Cpp_creator_ptr mt = (Cpp_creator_ptr)proc;
-#else
-    lib_name += ".so";
-    
-    void *lib_ptr = dlopen(lib_name.c_str(), RTLD_NOW);
-    if (lib_ptr == NULL)
-    {
-        TangoSys_OMemStream o;
-        o << "Trying to load shared library " << lib_name
-          << " failed. It returns error: " << dlerror() << ends;
-
-        Tango::Except::throw_exception("API_ClassNotFound",o.str(),
-                                       "DServer::create_cpp_class");
-    }
-
-    void *sym = dlsym(lib_ptr,sym_name.c_str());
-    if (sym == NULL)
-    {
-        TangoSys_OMemStream o;
-        o << "Class " << class_name << " does not have the C creator function "
-             "(_create_<Class name>_class)" << ends;
-
-        Tango::Except::throw_exception("API_ClassNotFound", o.str(),
-                                       "DServer::create_cpp_class");
-    }
-    Cpp_creator_ptr mt = (Cpp_creator_ptr)sym;
-#endif /* _TG_WINDOWS_ */
-    Tango::DeviceClass *dc = (*mt)(par_name.c_str());
-    return dc;
-}
-
 namespace PyUtil
 {
     void _class_factory(Tango::DServer* dserver)
@@ -121,11 +44,10 @@ namespace PyUtil
         int cl_len = len(cpp_class_list);
         for(int i = 0; i < cl_len; ++i)
         {
-            tuple class_info = extract<tuple>(cpp_class_list[i]);
+            bopy::tuple class_info = extract<bopy::tuple>(cpp_class_list[i]);
             char *class_name = extract<char *>(class_info[0]);
             char *par_name   = extract<char *>(class_info[1]);
-            Tango::DeviceClass* cpp_dc = create_cpp_class(class_name, par_name);
-            dserver->_add_class(cpp_dc);
+            dserver->_create_cpp_class(class_name, par_name);
         }
 
     //
@@ -171,10 +93,11 @@ namespace PyUtil
         Tango::Util* res = 0;
 
         try {
-
             for(int i = 0; i < argc; ++i)
             {
-                argv[i] = PyString_AsString(PySequence_GetItem(obj_ptr, i));
+                PyObject* item_ptr = PySequence_GetItem(obj_ptr, i);
+                str item = str(handle<>(item_ptr));
+                argv[i] = extract<char *>(item);
             }
             res = Tango::Util::init(argc, argv);
         } catch (...) {
@@ -296,6 +219,9 @@ void export_util()
         .def("trigger_attr_polling", &Tango::Util::trigger_attr_polling)
         .def("set_polling_threads_pool_size", &Tango::Util::set_polling_threads_pool_size)
         .def("get_polling_threads_pool_size", &Tango::Util::get_polling_threads_pool_size)
+        .def("is_svr_starting", &Tango::Util::is_svr_starting)
+        .def("is_svr_shutting_down", &Tango::Util::is_svr_shutting_down)        
+        .def("is_device_restarting", &Tango::Util::is_device_restarting)        
         .def("get_sub_dev_diag", &Tango::Util::get_sub_dev_diag,
             return_internal_reference<>())
         .def("connect_db", &Tango::Util::connect_db)
@@ -311,4 +237,4 @@ void export_util()
         .def("init_python", init_python)
         .staticmethod("init_python")
     ;
-}
\ No newline at end of file
+}
diff --git a/src/server/user_default_attr_prop.cpp b/src/server/user_default_attr_prop.cpp
index 3915b2e..b0b49ef 100644
--- a/src/server/user_default_attr_prop.cpp
+++ b/src/server/user_default_attr_prop.cpp
@@ -43,12 +43,19 @@ void export_user_default_attr_prop()
         .def("set_max_warning", &Tango::UserDefaultAttrProp::set_max_warning)
         .def("set_delta_t", &Tango::UserDefaultAttrProp::set_delta_t)
         .def("set_delta_val", &Tango::UserDefaultAttrProp::set_delta_val)
-        .def("set_abs_change", &Tango::UserDefaultAttrProp::set_abs_change)
-        .def("set_rel_change", &Tango::UserDefaultAttrProp::set_rel_change)
-        .def("set_period", &Tango::UserDefaultAttrProp::set_period)
-        .def("set_archive_abs_change", &Tango::UserDefaultAttrProp::set_archive_abs_change)
-        .def("set_archive_rel_change", &Tango::UserDefaultAttrProp::set_archive_rel_change)
-        .def("set_archive_period", &Tango::UserDefaultAttrProp::set_archive_period)
+        .def("set_abs_change", &Tango::UserDefaultAttrProp::set_event_abs_change)
+        .def("set_rel_change", &Tango::UserDefaultAttrProp::set_event_rel_change)
+        .def("set_period", &Tango::UserDefaultAttrProp::set_event_period)
+        .def("set_archive_abs_change", &Tango::UserDefaultAttrProp::set_archive_event_abs_change)
+        .def("set_archive_rel_change", &Tango::UserDefaultAttrProp::set_archive_event_rel_change)
+        .def("set_archive_period", &Tango::UserDefaultAttrProp::set_archive_event_period)
+
+        .def("set_event_abs_change", &Tango::UserDefaultAttrProp::set_event_abs_change)
+        .def("set_event_rel_change", &Tango::UserDefaultAttrProp::set_event_rel_change)
+        .def("set_event_period", &Tango::UserDefaultAttrProp::set_event_period)
+        .def("set_archive_event_abs_change", &Tango::UserDefaultAttrProp::set_archive_event_abs_change)
+        .def("set_archive_event_rel_change", &Tango::UserDefaultAttrProp::set_archive_event_rel_change)
+        .def("set_archive_event_period", &Tango::UserDefaultAttrProp::set_archive_event_period)
         
         .def_readwrite("label", &Tango::UserDefaultAttrProp::label)
         .def_readwrite("description", &Tango::UserDefaultAttrProp::description)
diff --git a/src/server/wattribute.cpp b/src/server/wattribute.cpp
index c7fa5fd..eb15e26 100644
--- a/src/server/wattribute.cpp
+++ b/src/server/wattribute.cpp
@@ -28,6 +28,10 @@
 
 using namespace boost::python;
 
+#ifndef TgLibVersNb
+#   define TgLibVersNb 80005
+#endif
+
 /**
  * Helper method to Limit the max number of element to send to C++
  *
@@ -83,9 +87,10 @@ namespace PyWAttribute
     {
         long type = att.get_data_type();
 
-        TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(type,
-            return __get_min_value<tangoTypeConst>(att)
-        );
+		if(type == Tango::DEV_ENCODED)
+			type = Tango::DEV_UCHAR;
+
+		TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, return __get_min_value, att);
         return 0;
     }
 
@@ -104,42 +109,129 @@ namespace PyWAttribute
     {
         long type = att.get_data_type();
 
-        TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(type,
-            return __get_max_value<tangoTypeConst>(att)
-        );
+		if(type == Tango::DEV_ENCODED)
+			type = Tango::DEV_UCHAR;
+
+		TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, return __get_max_value, att);
         return 0;
     }
 
+#if TgLibVersNb >= 80100 // set_min_value
+
     template<long tangoTypeConst>
-    void __set_min_value(Tango::WAttribute &att, boost::python::object &v)
+    inline void _set_min_value(Tango::WAttribute &self, boost::python::object value)
     {
-        typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+		typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+		self.set_min_value(c_value);
+    }
 
-        TangoScalarType tg_val = boost::python::extract<TangoScalarType>(v);
+#else // set_min_value
 
-        att.set_min_value(tg_val);
+    template<typename TangoScalarType>
+    inline void __set_min_value(Tango::WAttribute &self, boost::python::object value)
+    {
+		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+		self.set_min_value(c_value);
     }
 
-    void set_min_value(Tango::WAttribute &att, boost::python::object &v)
+    template<>
+    inline void __set_min_value<Tango::DevEncoded>(Tango::WAttribute &self, boost::python::object value)
     {
-        long type = att.get_data_type();
-        TANGO_CALL_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(type, __set_min_value, att, v);
+    	string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
+    	Tango::Except::throw_exception((const char *)"API_MethodArgument",
+    				  (const char *)err_msg.c_str(),
+    				  (const char *)"WAttribute::set_min_value()");
     }
 
     template<long tangoTypeConst>
-    void __set_max_value(Tango::WAttribute &att, boost::python::object &v)
+    inline void _set_min_value(Tango::WAttribute &self, boost::python::object value)
     {
-        typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+		typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+		__set_min_value<TangoScalarType>(self,value);
+    }
 
-        TangoScalarType tg_val = boost::python::extract<TangoScalarType>(v);
+#endif // set_min_value
 
-        att.set_max_value(tg_val);
+    inline void set_min_value(Tango::WAttribute &self, boost::python::object value)
+    {
+        bopy::extract<string> value_convert(value);
+        
+    	if (value_convert.check())
+    	{
+			self.set_min_value(value_convert());
+    	}
+    	else
+    	{
+			long tangoTypeConst = self.get_data_type();
+			// TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
+			// for one of the forbidden attribute data types; code dependent on Tango C++ implementation
+			if(tangoTypeConst == Tango::DEV_STRING || tangoTypeConst == Tango::DEV_BOOLEAN || tangoTypeConst == Tango::DEV_STATE)
+				tangoTypeConst = Tango::DEV_DOUBLE;
+			else if(tangoTypeConst == Tango::DEV_ENCODED)
+				tangoTypeConst = Tango::DEV_UCHAR;
+
+			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tangoTypeConst, _set_min_value, self, value);
+    	}
     }
 
-    void set_max_value(Tango::WAttribute &att, boost::python::object &v)
+#if TgLibVersNb >= 80100 // set_max_value
+
+    template<long tangoTypeConst>
+    inline void _set_max_value(Tango::WAttribute &self, boost::python::object value)
     {
-        long type = att.get_data_type();
-        TANGO_CALL_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(type, __set_max_value, att, v);
+		typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+		self.set_max_value(c_value);
+    }
+
+#else // set_max_value
+
+    template<typename TangoScalarType>
+    inline void __set_max_value(Tango::WAttribute &self, boost::python::object value)
+    {
+		TangoScalarType c_value = boost::python::extract<TangoScalarType>(value);
+		self.set_max_value(c_value);
+    }
+
+    template<>
+    inline void __set_max_value<Tango::DevEncoded>(Tango::WAttribute &self, boost::python::object value)
+    {
+    	string err_msg = "Attribute properties cannot be set with Tango::DevEncoded data type";
+    	Tango::Except::throw_exception((const char *)"API_MethodArgument",
+    				  (const char *)err_msg.c_str(),
+    				  (const char *)"WAttribute::set_max_value()");
+    }
+
+    template<long tangoTypeConst>
+    inline void _set_max_value(Tango::WAttribute &self, boost::python::object value)
+    {
+		typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
+		__set_max_value<TangoScalarType>(self,value);
+    }
+
+#endif // set_max_value
+
+    inline void set_max_value(Tango::WAttribute &self, boost::python::object value)
+    {
+        bopy::extract<string> value_convert(value);
+        
+    	if (value_convert.check())
+    	{
+			self.set_max_value(value_convert());
+    	}
+    	else
+    	{
+			long tangoTypeConst = self.get_data_type();
+			// TODO: the below line is a neat trick to properly raise a Tango exception if a property is set
+			// for one of the forbidden attribute data types; code dependent on Tango C++ implementation
+			if(tangoTypeConst == Tango::DEV_STRING || tangoTypeConst == Tango::DEV_BOOLEAN || tangoTypeConst == Tango::DEV_STATE)
+				tangoTypeConst = Tango::DEV_DOUBLE;
+			else if(tangoTypeConst == Tango::DEV_ENCODED)
+				tangoTypeConst = Tango::DEV_UCHAR;
+
+			TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tangoTypeConst, _set_max_value, self, value);
+    	}
     }
 /// @}
 
@@ -239,7 +331,7 @@ namespace PyWAttribute
 
         if (format == Tango::SCALAR)
         {
-            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __set_write_value_scalar,
+            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __set_write_value_scalar,
                                               att, value);
         }
         else
@@ -256,7 +348,7 @@ namespace PyWAttribute
                         o.str(),
                         "set_value()");
             }
-            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __set_write_value_array,
+            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __set_write_value_array,
                                               att, value,
                                               PySequence_Size(value.ptr()), 0);
         }
@@ -295,7 +387,7 @@ namespace PyWAttribute
                         o.str(),
                         "set_write_value()");
             }
-            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __set_write_value_array,
+            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __set_write_value_array,
                                               att, value, x, 0);
         }
     }
@@ -333,7 +425,7 @@ namespace PyWAttribute
                         o.str(),
                         (const char *)"set_write_value()");
             }
-            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __set_write_value_array,
+            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __set_write_value_array,
                                               att, value, x, y);
         }
     }
@@ -345,47 +437,6 @@ namespace PyWAttribute
 /// @{ 
 
     template<long tangoTypeConst>
-    void __get_write_value_pytango3(Tango::WAttribute &att, boost::python::list &seq)
-    {
-        typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
-
-        const TangoScalarType *ptr;
-
-        long length = att.get_write_value_length();
-
-        att.get_write_value(ptr);
-
-        for (long l = 0; l < length; ++l)
-        {
-            seq.append(ptr[l]);
-        }
-    }
-
-    template<>
-    void __get_write_value_pytango3<Tango::DEV_STRING>(Tango::WAttribute &att,
-                                              boost::python::list &seq)
-    {
-        const Tango::ConstDevString *ptr;
-
-        long length = att.get_write_value_length();
-
-        att.get_write_value(ptr);
-
-        for (long l = 0; l < length; ++l)
-        {
-            seq.append(ptr[l]);
-        }
-    }
-
-    inline void get_write_value_pytango3(Tango::WAttribute &att,
-                                boost::python::list &value)
-    {
-        long type = att.get_data_type();
-        TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __get_write_value_pytango3, att, value);
-    }
-
-
-    template<long tangoTypeConst>
     void __get_write_value_scalar(Tango::WAttribute &att, boost::python::object* obj)
     {
         typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
@@ -404,33 +455,6 @@ namespace PyWAttribute
     }
 
     template<long tangoTypeConst>
-    void __get_write_value_array_pytango3(Tango::WAttribute &att, boost::python::object* obj)
-    {
-        typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
-
-        const TangoScalarType * buffer;
-        att.get_write_value(buffer);
-        size_t length = att.get_write_value_length();
-        
-        boost::python::list o;
-        for (size_t n = 0; n < length; ++n)
-            o.append(buffer[n]);
-        *obj = o;
-    }
-
-    template<>
-    void __get_write_value_array_pytango3<Tango::DEV_STRING>(Tango::WAttribute &att, boost::python::object* obj)
-    {
-        const Tango::ConstDevString *ptr;
-        long length = att.get_write_value_length();
-        att.get_write_value(ptr);
-        boost::python::list o;
-        for (long l = 0; l < length; ++l)
-            o.append(ptr[l]);
-    }
-    
-
-    template<long tangoTypeConst>
     void __get_write_value_array_lists(Tango::WAttribute &att, boost::python::object* obj)
     {
         typedef typename TANGO_const2type(tangoTypeConst) TangoScalarType;
@@ -507,23 +531,18 @@ namespace PyWAttribute
         const bool isScalar = fmt == Tango::SCALAR;
 
         if (isScalar) {
-            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type, __get_write_value_scalar, att, &value);
+            TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type, __get_write_value_scalar, att, &value);
         } else {
             switch (extract_as) {
-                case PyTango::ExtractAsPyTango3: {
-                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type,
-                        __get_write_value_array_pytango3, att, &value);
-                    break;
-                }
                 case PyTango::ExtractAsNumpy: {
 #               ifndef DISABLE_PYTANGO_NUMPY
-                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type,
+                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type,
                         __get_write_value_array_numpy, att, &value);
                     break;
 #               endif
                 }
                 case PyTango::ExtractAsList: {
-                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(type,
+                    TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(type,
                         __get_write_value_array_lists, att, &value);
                     break;
                 }
@@ -546,7 +565,8 @@ namespace PyWAttribute
 void export_wattribute()
 {
 
-    class_<Tango::WAttribute, bases<Tango::Attribute> >("WAttribute", no_init)
+    class_<Tango::WAttribute, bases<Tango::Attribute>, boost::noncopyable>
+        ("WAttribute", no_init)
         .def("get_min_value",
             (PyObject* (*) (Tango::WAttribute &))
             &PyWAttribute::get_min_value)
@@ -567,13 +587,6 @@ void export_wattribute()
         .def("set_write_value",
             (void (*) (Tango::WAttribute &, boost::python::object &, long, long))
             &PyWAttribute::set_write_value)
-
-        // old style get_write_value
-        .def("get_write_value",
-            &PyWAttribute::get_write_value_pytango3,
-            ( arg_("self"), arg_("empty_list")))
-
-        // new style get_write_value
         .def("get_write_value",
             &PyWAttribute::get_write_value,
             ( arg_("self"), arg_("extract_as")=PyTango::ExtractAsNumpy ))
diff --git a/src/server/wattribute_numpy.hpp b/src/server/wattribute_numpy.hpp
index f26e90e..4ff7d1c 100644
--- a/src/server/wattribute_numpy.hpp
+++ b/src/server/wattribute_numpy.hpp
@@ -41,7 +41,7 @@ namespace PyWAttribute {
 
         // Copy buffer in a python raw buffer
         const char *original_ch_buffer = reinterpret_cast<const char *>(buffer);
-        PyObject* str_guard = PyString_FromStringAndSize(original_ch_buffer, length*sizeof(TangoScalarType));
+        PyObject* str_guard = PyBytes_FromStringAndSize(original_ch_buffer, length*sizeof(TangoScalarType));
 
         if (!str_guard) {
             throw_error_already_set();
@@ -52,7 +52,7 @@ namespace PyWAttribute {
         npy_intp dims[2];
         int nd = 1;
 
-        char* ch_buffer = PyString_AsString(str_guard);
+        char* ch_buffer = PyBytes_AsString(str_guard);
 
         if (att.get_data_format() == Tango::IMAGE) {
             nd = 2;
diff --git a/src/tgutils.h b/src/tgutils.h
index 6bd10f3..5a8f9ef 100644
--- a/src/tgutils.h
+++ b/src/tgutils.h
@@ -26,6 +26,10 @@
 #include <cassert>
 #include <tango.h>
 
+#ifndef TgLibVersNb
+#   define TgLibVersNb 80005
+#endif
+
 namespace Tango
 {
     typedef std::vector<DbHistory> DbHistoryList;
@@ -163,88 +167,173 @@ DEF_TANGO_SCALAR_ARRAY_NAMES( DEV_ULONG64, DEVVAR_ULONG64ARRAY );
 
 
 
-#define __TANGO_DEPEND_ON_TYPE_AUX(typename_, DOIT) \
+#define __TANGO_DEPEND_ON_TYPE_AUX_ID(typename_, DOIT) \
     case Tango:: typename_: { \
         static const long tangoTypeConst = Tango:: typename_; \
         DOIT; \
         break; \
     }
 
-#define TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(tid, DOIT) if (true) { \
+#define __TANGO_DEPEND_ON_TYPE_AUX_NAME(tid_, DOIT) \
+    case Tango:: tid_: { \
+        typedef typename TANGO_const2type(Tango:: tid_) TangoType; \
+        DOIT; \
+        break; \
+    }
+
+#define TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_ID(tid, DOIT) if (true) { \
+    switch(tid) { \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_SHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_LONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_DOUBLE, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_STRING, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_FLOAT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_BOOLEAN, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_USHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ULONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_UCHAR, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_LONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ULONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_STATE, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ENCODED, DOIT) \
+        default: \
+            assert(false); \
+    } } else (void)0
+
+#define TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_NAME(tid, DOIT) if (true) { \
     switch(tid) { \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_SHORT, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_LONG, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_DOUBLE, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_STRING, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_FLOAT, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_BOOLEAN, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_USHORT, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ULONG, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_UCHAR, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_LONG64, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ULONG64, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_STATE, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ENCODED, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_SHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_LONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_DOUBLE, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_STRING, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_FLOAT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_BOOLEAN, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_USHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ULONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_UCHAR, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_LONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ULONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_STATE, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ENCODED, DOIT) \
         default: \
             assert(false); \
     } } else (void)0
 
-#define TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE(tid, fn, ...) \
-    TANGO_DO_ON_ATTRIBUTE_DATA_TYPE(tid, fn<tangoTypeConst>(__VA_ARGS__))
+#define TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_ID(tid, fn, ...) \
+    TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_ID(tid, fn<tangoTypeConst>(__VA_ARGS__))
+
+#define TANGO_CALL_ON_ATTRIBUTE_DATA_TYPE_NAME(tid, fn, ...) \
+    TANGO_DO_ON_ATTRIBUTE_DATA_TYPE_NAME(tid, fn<TangoType>(__VA_ARGS__))
 
 /// @todo Not sure about who I choosed to comment out from here...
-#define TANGO_DO_ON_DEVICE_DATA_TYPE(tid, DOIT_SIMPLE, DOIT_ARRAY) if (true) { \
+#define TANGO_DO_ON_DEVICE_DATA_TYPE_ID(tid, DOIT_SIMPLE, DOIT_ARRAY) if (true) { \
     switch(tid) { \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_VOID, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_BOOLEAN, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_SHORT, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_LONG, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_FLOAT, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_DOUBLE, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_USHORT, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ULONG, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_STRING, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_CHARARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_SHORTARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_LONGARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_FLOATARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_DOUBLEARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_USHORTARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_ULONGARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_STRINGARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_LONGSTRINGARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_DOUBLESTRINGARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_STATE, DOIT_SIMPLE) \
-/*        __TANGO_DEPEND_ON_TYPE_AUX(CONST_DEV_STRING, DOIT_SIMPLE) */\
-/*        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_BOOLEANARRAY, DOIT_ARRAY) */\
-/*        __TANGO_DEPEND_ON_TYPE_AUX(DEV_UCHAR, DOIT_SIMPLE)*/ \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_LONG64, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ULONG64, DOIT_SIMPLE) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_LONG64ARRAY, DOIT_ARRAY) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEVVAR_ULONG64ARRAY, DOIT_ARRAY) \
-/*        __TANGO_DEPEND_ON_TYPE_AUX(DEV_INT, DOIT_SIMPLE) */\
-/*        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ENCODED, DOIT_SIMPLE)*/ \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_VOID, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_BOOLEAN, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_SHORT, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_LONG, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_FLOAT, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_DOUBLE, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_USHORT, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ULONG, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_STRING, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_CHARARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_SHORTARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_LONGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_FLOATARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_DOUBLEARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_USHORTARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_ULONGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_STRINGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_LONGSTRINGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_DOUBLESTRINGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_STATE, DOIT_SIMPLE) \
+/*        __TANGO_DEPEND_ON_TYPE_AUX_ID(CONST_DEV_STRING, DOIT_SIMPLE) */\
+/*        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_BOOLEANARRAY, DOIT_ARRAY) */\
+/*        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_UCHAR, DOIT_SIMPLE)*/ \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_LONG64, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ULONG64, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_LONG64ARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEVVAR_ULONG64ARRAY, DOIT_ARRAY) \
+/*        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_INT, DOIT_SIMPLE) */\
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ENCODED, DOIT_SIMPLE) \
         default: \
             assert(false); \
     } } else (void)0
 
-#define TANGO_CALL_ON_DEVICE_DATA_TYPE(tid, fn_simple, fn_array, ...) \
-    TANGO_DO_ON_DEVICE_DATA_TYPE(tid, fn_simple<tangoTypeConst>(__VA_ARGS__), fn_array<tangoTypeConst>(__VA_ARGS__))
+#define TANGO_DO_ON_DEVICE_DATA_TYPE_NAME(tid, DOIT_SIMPLE, DOIT_ARRAY) if (true) { \
+    switch(tid) { \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_VOID, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_BOOLEAN, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_SHORT, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_LONG, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_FLOAT, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_DOUBLE, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_USHORT, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ULONG, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_STRING, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_CHARARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_SHORTARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_LONGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_FLOATARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_DOUBLEARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_USHORTARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_ULONGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_STRINGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_LONGSTRINGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_DOUBLESTRINGARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_STATE, DOIT_SIMPLE) \
+/*        __TANGO_DEPEND_ON_TYPE_AUX_NAME(CONST_DEV_STRING, DOIT_SIMPLE) */\
+/*        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_BOOLEANARRAY, DOIT_ARRAY) */\
+/*        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_UCHAR, DOIT_SIMPLE)*/ \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_LONG64, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ULONG64, DOIT_SIMPLE) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_LONG64ARRAY, DOIT_ARRAY) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEVVAR_ULONG64ARRAY, DOIT_ARRAY) \
+/*        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_INT, DOIT_SIMPLE) */\
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ENCODED, DOIT_SIMPLE) \
+        default: \
+            assert(false); \
+    } } else (void)0
 
-#define TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(tid, DOIT) if (true) { \
+#define TANGO_CALL_ON_DEVICE_DATA_TYPE_ID(tid, fn_simple, fn_array, ...) \
+    TANGO_DO_ON_DEVICE_DATA_TYPE_ID(tid, fn_simple<tangoTypeConst>(__VA_ARGS__), fn_array<tangoTypeConst>(__VA_ARGS__))
+
+#define TANGO_CALL_ON_DEVICE_DATA_TYPE_NAME(tid, fn_simple, fn_array, ...) \
+    TANGO_DO_ON_DEVICE_DATA_TYPE_NAME(tid, fn_simple<TangoType>(__VA_ARGS__), fn_array<TangoType>(__VA_ARGS__))
+
+#define TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE_ID(tid, DOIT) if (true) { \
     switch(tid) { \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_SHORT, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_LONG, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_DOUBLE, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_FLOAT, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_USHORT, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ULONG, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_UCHAR, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_LONG64, DOIT) \
-        __TANGO_DEPEND_ON_TYPE_AUX(DEV_ULONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_SHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_LONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_DOUBLE, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_FLOAT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_USHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ULONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_UCHAR, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_LONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_ID(DEV_ULONG64, DOIT) \
         default: \
             assert(false); \
     } } else (void)0
 
-#define TANGO_CALL_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(tid, fn, ...) \
-    TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE(tid, fn<tangoTypeConst>(__VA_ARGS__))
+#define TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE_NAME(tid, DOIT) if (true) { \
+    switch(tid) { \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_SHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_LONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_DOUBLE, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_FLOAT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_USHORT, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ULONG, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_UCHAR, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_LONG64, DOIT) \
+        __TANGO_DEPEND_ON_TYPE_AUX_NAME(DEV_ULONG64, DOIT) \
+        default: \
+            assert(false); \
+    } } else (void)0
+
+#define TANGO_CALL_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE_ID(tid, fn, ...) \
+    TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE_ID(tid, fn<tangoTypeConst>(__VA_ARGS__))
+
+#define TANGO_CALL_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE_NAME(tid, fn, ...) \
+    TANGO_DO_ON_NUMERICAL_ATTRIBUTE_DATA_TYPE_NAME(tid, fn<tangoTypeConst>(__VA_ARGS__))
diff --git a/src/to_py.cpp b/src/to_py.cpp
index a7932f4..c093e52 100644
--- a/src/to_py.cpp
+++ b/src/to_py.cpp
@@ -222,4 +222,4 @@ boost::python::list to_py(const Tango::AttributeConfigList_3 &attr_conf_list)
         py_attr_conf_list.append(to_py(attr_conf, none));
     }
     return py_attr_conf_list;
-}
\ No newline at end of file
+}
diff --git a/src/to_py.h b/src/to_py.h
index d094fa4..c394c26 100644
--- a/src/to_py.h
+++ b/src/to_py.h
@@ -27,14 +27,17 @@
 #include <tango.h>
 
 #include "defs.h"
+#include "pyutils.h"
 
 struct DevEncoded_to_tuple
 {
     static inline PyObject* convert(Tango::DevEncoded const& a)
     {
         boost::python::str encoded_format(a.encoded_format);
-        boost::python::str encoded_data(
-            (const char*)a.encoded_data.get_buffer(), a.encoded_data.length());
+        bopy::object encoded_data = bopy::object(
+            bopy::handle<>(PyBytes_FromStringAndSize(
+                (const char*)a.encoded_data.get_buffer(),
+                (Py_ssize_t)a.encoded_data.length())));
         boost::python::object result = boost::python::make_tuple(encoded_format, encoded_data);
         return boost::python::incref(result.ptr());
     }
@@ -104,6 +107,7 @@ struct CORBA_sequence_to_tuple<Tango::DevVarStringArray>
         PyObject *t = PyTuple_New(size);
         for(unsigned long i=0; i < size; ++i)
         {
+            
             boost::python::str x(a[i].in());
             PyTuple_SetItem(t, i, boost::python::incref(x.ptr()));
         }
@@ -272,30 +276,50 @@ struct CORBA_String_member_to_str
 {
     static inline PyObject* convert(CORBA::String_member const& cstr)
     {
-        return boost::python::incref(boost::python::str(cstr.in()).ptr());
+        return from_char_to_str(cstr.in());
     }
 
-    static const PyTypeObject* get_pytype() { return &PyString_Type; }
+    //static const PyTypeObject* get_pytype() { return &PyBytes_Type; }
 };
 
 struct CORBA_String_member_to_str2
 {
     static inline PyObject* convert(_CORBA_String_member const& cstr)
     {
-        return boost::python::incref(boost::python::str(cstr.in()).ptr());
+        return from_char_to_str(cstr.in());
     }
 
-    static const PyTypeObject* get_pytype() { return &PyString_Type; }
+    //static const PyTypeObject* get_pytype() { return &PyBytes_Type; }
 };
 
 struct CORBA_String_element_to_str
 {
     static inline PyObject* convert(_CORBA_String_element const& cstr)
     {
-        return boost::python::incref(boost::python::str(cstr.in()).ptr());
+        return from_char_to_str(cstr.in());
     }
 
-    static const PyTypeObject* get_pytype() { return &PyString_Type; }
+    //static const PyTypeObject* get_pytype() { return &PyBytes_Type; }
+};
+
+struct String_to_str
+{
+    static inline PyObject* convert(std::string const& cstr)
+    {
+        return from_char_to_str(cstr);
+    }
+
+    //static const PyTypeObject* get_pytype() { return &PyBytes_Type; }
+};
+
+struct char_ptr_to_str
+{
+    static inline PyObject* convert(const char *cstr)
+    {
+        return from_char_to_str(cstr);
+    }
+
+    //static const PyTypeObject* get_pytype() { return &PyBytes_Type; }
 };
 
 boost::python::object to_py(const Tango::AttributeAlarm &);
@@ -304,6 +328,37 @@ boost::python::object to_py(const Tango::PeriodicEventProp &);
 boost::python::object to_py(const Tango::ArchiveEventProp &);
 boost::python::object to_py(const Tango::EventProperties &);
 
+template<typename T>
+void to_py(Tango::MultiAttrProp<T> &multi_attr_prop, boost::python::object &py_multi_attr_prop)
+{
+    if(py_multi_attr_prop.ptr() == Py_None)
+    {
+        PYTANGO_MOD
+        py_multi_attr_prop = pytango.attr("MultiAttrProp")();
+    }
+
+    py_multi_attr_prop.attr("label") = multi_attr_prop.label;
+    py_multi_attr_prop.attr("description") = multi_attr_prop.description;
+    py_multi_attr_prop.attr("unit") = multi_attr_prop.unit;
+    py_multi_attr_prop.attr("standard_unit") = multi_attr_prop.standard_unit;
+    py_multi_attr_prop.attr("display_unit") = multi_attr_prop.display_unit;
+    py_multi_attr_prop.attr("format") = multi_attr_prop.format;
+    py_multi_attr_prop.attr("min_value") = multi_attr_prop.min_value.get_str();
+    py_multi_attr_prop.attr("max_value") = multi_attr_prop.max_value.get_str();
+    py_multi_attr_prop.attr("min_alarm") = multi_attr_prop.min_alarm.get_str();
+    py_multi_attr_prop.attr("max_alarm") = multi_attr_prop.max_alarm.get_str();
+    py_multi_attr_prop.attr("min_warning") = multi_attr_prop.min_warning.get_str();
+    py_multi_attr_prop.attr("max_warning") = multi_attr_prop.max_warning.get_str();
+    py_multi_attr_prop.attr("delta_t") = multi_attr_prop.delta_t.get_str();
+    py_multi_attr_prop.attr("delta_val") = multi_attr_prop.delta_val.get_str();
+    py_multi_attr_prop.attr("event_period") = multi_attr_prop.event_period.get_str();
+    py_multi_attr_prop.attr("archive_period") = multi_attr_prop.archive_period.get_str();
+    py_multi_attr_prop.attr("rel_change") = multi_attr_prop.rel_change.get_str();
+    py_multi_attr_prop.attr("abs_change") = multi_attr_prop.abs_change.get_str();
+    py_multi_attr_prop.attr("archive_rel_change") = multi_attr_prop.archive_rel_change.get_str();
+    py_multi_attr_prop.attr("archive_abs_change") = multi_attr_prop.archive_abs_change.get_str();
+}
+
 boost::python::object to_py(const Tango::AttributeConfig &, 
                             boost::python::object py_attr_conf);
 boost::python::object to_py(const Tango::AttributeConfig_2 &,
diff --git a/tests/DevTest.py b/tests/DevTest.py
new file mode 100644
index 0000000..0dfedad
--- /dev/null
+++ b/tests/DevTest.py
@@ -0,0 +1,2895 @@
+
+import PyTango
+import sys
+import os
+import time
+import string
+import threading
+from twisted.plugins.cred_anonymous import theAnonymousCheckerFactory
+
+class EventCallBack:
+    def __init__(self):
+        self.cb_executed = 0
+        self.cb_err = 0
+        self.old_sec = 0
+        self.old_usec = 0 
+        self.delta_msec = 0
+        
+    def push_event(self, event_data):
+        if sys.platform == 'win32':
+            gettime = time.clock
+        else:
+            gettime = time.time
+        t = gettime()
+        sec = int(t)
+        usec = int((t - sec) * 1000000)
+        print('date : tv_sec = ' + str(sec) + ', tv_usec = ' + str(usec))
+        delta_msec = int(((sec - self.old_sec) * 1000000 + (usec - self.old_usec)) / 1000)
+        self.old_sec = sec
+        self.old_usec = usec
+        print('delta_msec = ' + str(delta_msec))
+        self.cb_executed += 1
+        try:
+            print('StateEventCallBack::push_event(): called attribute ' + event_data.attr_name + ' event ' + event_data.event)
+            if event_data.err == False:
+                print('CallBack vector value : ' + str(event_data.attr_value.value))
+            else:
+                print('Error send to callback')
+                if event_data.errors[0].reason == 'aaa':
+                    self.cb_err += 1
+        except:
+            print('EventCallBack::push_event(): could not extract data !')
+        
+
+class DevTest(PyTango.Device_4Impl):
+    def __init__(self,cl,name):
+        PyTango.Device_4Impl.__init__(self,cl,name)
+        print('In DevTest __init__')
+        DevTest.init_device(self)
+
+    def init_device(self):
+        print('In Python init_device method')
+        self.set_state(PyTango.DevState.ON)
+
+        self.Short_attr_except = False
+        self.event_change_attr_except = False
+        self.event_quality_attr_except = False
+        self.event_throw_out_of_sync = False
+
+        self.attr_long = 1246
+        self.attr_short_rw = 66;
+        self.attr_long_rw2 = -1
+        self.PollLong_attr_num = 0;
+        self.PollString_spec_attr_num = 0;
+
+        self.attr_short_array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
+        self.attr_long_array = [1,2,3,4,5,6,7,8,9,10]
+        self.attr_db_array = [7.77,8.88,9.99]
+        self.attr_str_array = ['a','b']
+
+        self.attr_short_rw = 66
+
+        self.attr_spec_float = [1,2,3]
+        self.attr_spec_boolean = [1,2,3,4,5]
+        self.attr_spec_ushort = [1,2]
+        self.attr_spec_uchar = [1,2,3,4,5,6]
+        self.Long_spec_attr_rw = [1,2,3,4]
+
+        self.num_cmd1 = 0
+        self.num_cmd2 = 0
+        self.attr_event_size = 4
+        self.attr_event = [10,20,30,40,50,60,70,80,90,100]
+        self.attr_event64_size = 2
+        self.attr_event64 = [0x800000000,44,55]
+        self.attr_qua_event = [1.2,2.4]
+        self.attr_event_qua = PyTango.AttrQuality.ATTR_VALID
+
+        self.fast_actua = 0.0
+        self.slow_actua = 0
+        self.slow_actua_write = 0
+        
+        self.enc_attr_data = bytearray([97,98,99,100])
+        self.enc_attr = ['Which format?', self.enc_attr_data] #''.join(chr(i) for i in self.enc_attr_data).encode('utf-8')]
+        self.enc_format_toggle = False
+        self.encoded_cmd_ctr = 0
+        self.remote_dev = None
+        self.cb = EventCallBack()
+        self.eve_id = 0
+        
+        self.attr_ulong_rw = 0xC0000000
+        self.attr_ulong64_rw = 0xC000000000000000
+        
+        self.attr_state_rw = PyTango.DevState.FAULT
+        self.attr_spec_ulong_rw = [2222,22222,222222]
+        self.attr_spec_ulong64_rw = [8888,88888,888888]
+        self.attr_spec_state_rw = [PyTango.DevState.ON,PyTango.DevState.OFF]
+        self.attr_sub_device_tst = False
+        self.attr_slow = 3.3
+        self.att_conf = 10
+
+#------------------------------------------------------------------
+
+    def delete_device(self):
+        print('[Device delete_device method] for device',self.get_name())
+
+#------------------------------------------------------------------
+
+    def signal_handler(self,in_sig):
+        print('[Device signal handler] received signal number',in_sig,' for device',self.get_name())
+
+#------------------------------------------------------------------
+
+#    def State(self):
+#        print "[Device] In my own State method"
+#        sta = PyTango.Device_3Impl.dev_state(self)
+#        print 'Original state =',sta
+#        self.set_state(PyTango.DevState.STANDBY)
+#        return self.get_state()
+
+#------------------------------------------------------------------
+
+#    def Status(self):
+#        print "[Device] In my own Status method"
+#        self.st = PyTango.Device_3Impl.dev_status(self)
+#        print "Status =",self.st
+#        self.st = self.st + " Si,si...."
+#        return self.st
+
+#------------------------------------------------------------------
+
+    def is_IOVoid_allowed(self):
+        print('In is_IOVoid_allowed method')
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOVoid(self):
+        print('[IOVoid::execute] ')
+
+#------------------------------------------------------------------
+
+    def is_IOBool_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOBool(self,in_bool):
+        print('[IOBool::execute] received number',in_bool,' type = ',type(in_bool))
+        if (in_bool == True):
+            in_bool = False
+        else:
+            in_bool = True
+        print('[IOBool::execute] return number',in_bool)
+        return in_bool;
+
+#------------------------------------------------------------------
+
+    def is_IOShort_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOShort(self,in_data):
+        print('[IOShort::execute] received number',in_data,' type = ',type(in_data))
+        in_data = in_data * 2;
+        print('[IOShort::execute] return number',in_data)
+        return in_data;
+
+#------------------------------------------------------------------
+
+    def is_IOLong_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOLong(self,in_data):
+        print('[IOLong::execute] received number',in_data,' type = ',type(in_data))
+        in_data = in_data * 2;
+        print('[IOLong::execute] return number',in_data)
+        return in_data;
+
+#------------------------------------------------------------------
+
+    def is_IOFloat_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOFloat(self,in_data):
+        print('[IOFloat::execute] received number',in_data,' type = ',type(in_data))
+        in_data = in_data * 2;
+        print('[IOFloat::execute] return number',in_data)
+        return in_data;
+
+#------------------------------------------------------------------
+
+    def is_IODouble_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IODouble(self,in_data):
+        print('[IODouble::execute] received number',in_data,' type = ',type(in_data))
+        in_data = in_data * 2;
+        print('[IODouble::execute] return number',in_data)
+        return in_data;
+
+#------------------------------------------------------------------
+
+    def is_IOUShort_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOUShort(self,in_data):
+        print('[IOUShort::execute] received number',in_data,' type = ',type(in_data))
+        in_data = in_data * 2;
+        print('[IOUShort::execute] return number',in_data)
+        return in_data;
+
+#------------------------------------------------------------------
+
+    def is_IOULong_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOULong(self,in_data):
+        print('[IOULong::execute] received number',in_data,' type = ',type(in_data))
+        in_data = in_data * 2;
+        print('[IOULong::execute] return number',in_data)
+        return in_data;
+
+#------------------------------------------------------------------
+
+    def is_IOString_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOString(self,in_data):
+        print("[IOString::execute] received string",in_data," type = ",type(in_data))
+        l = range(len(in_data) - 1,-1,-1)
+        out_data=""
+        for i in l:
+            out_data = out_data + in_data[i]
+        print("[IOString::execute] return string",out_data)
+#        self.y = out_data
+        return out_data;
+
+#------------------------------------------------------------------
+
+    def is_IOCharArray_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOCharArray(self,in_data):
+        l = range(len(in_data)-1,-1,-1);
+        out_index=0
+        out_data=[]
+        for i in l:
+            print("[IOCharArray::execute] received char",in_data[out_index])
+            out_data.append(in_data[i])
+            print("[IOStringArray::execute] return char",out_data[out_index])
+            out_index = out_index+1
+        return out_data
+
+#------------------------------------------------------------------
+
+    def is_IOShortArray_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOShortArray(self,in_data):
+        l = range(len(in_data));
+        for i in l:
+            print("[IOShortArray::execute] received number",in_data[i])
+            in_data[i] = in_data[i] * 2
+            print("[IOShortArray::execute] return number",in_data[i])
+        return in_data
+
+
+#------------------------------------------------------------------
+
+    def is_IOLongArray_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOLongArray(self,in_data):
+        l = range(len(in_data));
+        for i in l:
+            print("[IOLongArray::execute] received number",in_data[i])
+            in_data[i] = in_data[i] * 2
+            print("[IOLongArray::execute] return number",in_data[i])
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IOFloatArray_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOFloatArray(self,in_data):
+        l = range(len(in_data));
+        for i in l:
+            print("[IOFloatArray::execute] received number",in_data[i])
+            in_data[i] = in_data[i] * 2
+            print("[IOFloatArray::execute] return number",in_data[i])
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IODoubleArray_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IODoubleArray(self,in_data):
+        l = range(len(in_data));
+        for i in l:
+            print("[IODoubleArray::execute] received number",in_data[i])
+            in_data[i] = in_data[i] * 2
+            print("[IODoubleArray::execute] return number",in_data[i])
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IOUShortArray_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOUShortArray(self,in_data):
+        l = range(len(in_data));
+        for i in l:
+            print("[IOUShortArray::execute] received number",in_data[i])
+            in_data[i] = in_data[i] * 2
+            print("[IOUShortArray::execute] return number",in_data[i])
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IOULongArray_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOULongArray(self,in_data):
+        l = range(len(in_data));
+        for i in l:
+            print("[IOULongArray::execute] received number",in_data[i])
+            in_data[i] = in_data[i] * 2
+            print("[IOULongArray::execute] return number",in_data[i])
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IOStringArray_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOStringArray(self,in_data):
+        l = range(len(in_data)-1,-1,-1);
+        out_index=0
+        out_data=[]
+        for i in l:
+            print("[IOStringArray::execute] received String",in_data[out_index])
+            out_data.append(in_data[i])
+            print("[IOStringArray::execute] return String",out_data[out_index])
+            out_index = out_index+1
+        return out_data
+
+#------------------------------------------------------------------
+
+    def is_IOLongString_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOLongString(self,in_data):
+        l = range(len(in_data[0]))
+        for i in l:
+            print("[IOLongString::execute] received number",in_data[0][i])
+            in_data[0][i] = in_data[0][i] * 2
+            print("[IOLongString::execute] return number",in_data[0][i])
+
+        l = range(len(in_data[1]))
+        for i in l:
+            print("[IOLongString::execute] received string",in_data[1][i])
+            print("[IOLongString::execute] return string",in_data[1][i])
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IODoubleString_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IODoubleString(self,in_data):
+        l = range(len(in_data[0]))
+        for i in l:
+            print("[IODoubleString::execute] received number",in_data[0][i])
+            in_data[0][i] = in_data[0][i] * 2
+            print("[IODoubleString::execute] return number",in_data[0][i])
+
+        l = range(len(in_data[1]))
+        for i in l:
+            print("[IODoubleString::execute] received string",in_data[1][i])
+            print("[IODoubleString::execute] return string",in_data[1][i])
+        return in_data
+
+#------------------------------------------------------------------
+
+    def IOState(self,in_data):
+        print "[IOState::execute] received state",in_data
+        self.set_state(in_data)
+
+#------------------------------------------------------------------
+
+    def is_IOThrow_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOThrow(self,in_data):
+        print "[IOThrow::execute] throwing severity exception",in_data[0][0]
+        if (in_data[0][0] == PyTango.ErrSeverity.WARN):
+            PyTango.Except.throw_exception(in_data[1][0],'This is a test','IOThrow::execute()',PyTango.ErrSeverity.WARN)
+        elif (in_data[0][0] == PyTango.ErrSeverity.ERR):
+            PyTango.Except.throw_exception(in_data[1][0],'This is a test','IOThrow::execute()',PyTango.ErrSeverity.ERR)
+        if (in_data[0][0] == PyTango.ErrSeverity.PANIC):
+            PyTango.Except.throw_exception(in_data[1][0],'This is a test','IOThrow::execute()',PyTango.ErrSeverity.PANIC)
+
+
+
+#------------------------------------------------------------------
+
+    def is_IOReThrow_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOReThrow(self,in_data):
+        nb_except = len(in_data[0])
+        print "[IOReThrow::execute] throwing",nb_except,"exception(s)"
+        try:
+            if (in_data[0][0] == PyTango.ErrSeverity.WARN):
+                PyTango.Except.throw_exception(in_data[1][0],'This is a test','IOThrow::execute()',PyTango.ErrSeverity.WARN)
+            elif (in_data[0][0] == PyTango.ErrSeverity.ERR):
+                PyTango.Except.throw_exception(in_data[1][0],'This is a test','IOThrow::execute()',PyTango.ErrSeverity.ERR)
+            elif (in_data[0][0] == PyTango.ErrSeverity.PANIC):
+                PyTango.Except.throw_exception(in_data[1][0],'This is a test','IOThrow::execute()',PyTango.ErrSeverity.PANIC)
+        except PyTango.DevFailed,e:
+            if (nb_except > 2):
+                ind = 1
+                for i in range(nb_except - 2):
+                    try:
+                        sev = in_data[0][ind]
+                        if (sev == PyTango.ErrSeverity.WARN):
+                            PyTango.Except.re_throw_exception(e,in_data[1][ind],'This is a test','IOReThrow::execute()',PyTango.ErrSeverity.WARN)
+                        elif (sev == PyTango.ErrSeverity.ERR):
+                            PyTango.Except.re_throw_exception(e,in_data[1][ind],'This is a test','IOReThrow::execute()',PyTango.ErrSeverity.ERR)
+                        elif (sev == PyTango.ErrSeverity.PANIC):
+                            PyTango.Except.re_throw_exception(e,in_data[1][ind],'This is a test','IOReThrow::execute()',PyTango.ErrSeverity.PANIC)
+                    except PyTango.DevFailed,ex:
+                        ind = ind + 1
+                        e = ex
+
+
+            last_sever = in_data[0][nb_except - 1]
+            if (last_sever == PyTango.ErrSeverity.WARN):
+                PyTango.Except.re_throw_exception(e,in_data[1][nb_except-1],'This is a test','IOReThrow::execute()',PyTango.ErrSeverity.WARN)
+            elif (last_sever == PyTango.ErrSeverity.ERR):
+                PyTango.Except.re_throw_exception(e,in_data[1][nb_except-1],'This is a test','IOReThrow::execute()',PyTango.ErrSeverity.ERR)
+            elif (last_sever == PyTango.ErrSeverity.PANIC):
+                PyTango.Except.re_throw_exception(e,in_data[1][nb_except-1],'This is a test','IOReThrow::execute()',PyTango.ErrSeverity.PANIC)
+
+#------------------------------------------------------------------
+
+    def is_IODevByName_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IODevByName(self,in_data):
+        try:
+            print "[IODevByName::execute] received dev name",in_data
+            U = PyTango.Util.instance()
+            dev = U.get_device_by_name(in_data)
+            self.name = dev.get_name()
+            return self.name
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def is_IODServDevice_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IODServDevice(self):
+        try:
+            print "[IODServDevice::execute]"
+            U = PyTango.Util.instance()
+            dev = U.get_dserver_device()
+            self.name = dev.get_name()
+            return self.name
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def is_IODevListByClass_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IODevListByClass(self,in_data):
+        try:
+            print "[IODevListByClass::execute] received class name",in_data
+            U = PyTango.Util.instance()
+            dev_list = U.get_device_list_by_class(in_data)
+            print dev_list.size()," devices in class", in_data
+            name = dev_list.at(0).get_name()
+            self.ret_name = name[:string.rfind(name,'/')]
+            return self.ret_name
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def IOInitWAttr(self):
+        self.dev_m_attr = self.get_device_attr()
+        self.w_attr = self.dev_m_attr.get_w_attr_by_name("Short_attr_w")
+        self.w_attr.set_write_value(10)
+
+        self.w_attr = self.dev_m_attr.get_w_attr_by_name("Long_attr_w")
+        self.w_attr.set_write_value(100);
+
+        self.w_attr = self.dev_m_attr.get_w_attr_by_name("Double_attr_w")
+        self.w_attr.set_write_value(1.1);
+
+        self.w_attr = self.dev_m_attr.get_w_attr_by_name("String_attr_w")
+        self.w_attr.set_write_value("Init");
+
+#------------------------------------------------------------------
+
+    def is_IOSetAttr_allowed(self):
+        if ((self.get_state() == PyTango.DevState.ON) or (self.get_state() == PyTango.DevState.ALARM)):
+            return True
+        else:
+            return False
+
+
+    def IOSetAttr(self,in_data):
+        try:
+            print "[IOSetAttr::execute] received number ",in_data
+            self.attr_long = in_data
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def is_IOAddAttribute_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOAddAttribute(self):
+        try:
+            print "[IOAddAttribute::execute] "
+            at = PyTango.Attr("Added_short_attr", PyTango.ArgType.DevShort, PyTango.AttrWriteType.READ)
+            def_prop = PyTango.UserDefaultAttrProp()
+            def_prop.set_label("Test label");
+            def_prop.set_description("Test description");
+            def_prop.set_format("Illisible");
+            at.set_default_properties(def_prop);
+            self.add_attribute(at);
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def is_IORegSig_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IORegSig(self,in_data):
+        try:
+            print "[IORegSig::execute] received signal number ",in_data
+            self.register_signal(in_data)
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+
+    def is_IOUnregSig_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOUnregSig(self,in_data):
+        try:
+            print "[IOUnregSig::execute] received signal number ",in_data
+            self.unregister_signal(in_data)
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def is_IORegClassSig_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IORegClassSig(self,in_data):
+        try:
+            print "[IORegClassSig::execute] received signal number ",in_data
+            dc = self.get_device_class()
+            dc.register_signal(in_data)
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def is_IOUnregClassSig_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOUnregClassSig(self,in_data):
+        try:
+            print "[IOUnregClassSig::execute] received signal number ",in_data
+            ds = self.get_device_class()
+            ds.unregister_signal(in_data)
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def is_IOStr1_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOStr1(self):
+        try:
+            out_data = "Hello from IOStr1"
+            self.y = out_data
+            return out_data;
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def is_IOStr2_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOStr2(self):
+        try:
+            out_data = "Hello from IOStr2"
+            self.y = out_data
+            return out_data;
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def is_IOExcept_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOExcept(self):
+        PyTango.Except.throw_exception("API_ThrowException","This is a test ","IOExcept::execute()")
+
+#------------------------------------------------------------------
+
+    def IOStartPoll(self):
+        return 11
+
+#------------------------------------------------------------------
+
+    def is_IOPollStr1_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOPollStr1(self):
+        try:
+            self.num_cmd1 += 1
+            if ((self.num_cmd1 % 2) == 0):
+                return "Even value from IOPollStr1"
+            else:
+                return "Odd value from IOPollStr1"
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def is_IOPollArray2_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOPollArray2(self):
+        try:
+            self.num_cmd2 += 1
+            if ((self.num_cmd2 % 2) == 0):
+                self.attr_short_array = [100,200]
+            else:
+                self.attr_short_array = [300,400]
+                return self.attr_short_array
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+
+#------------------------------------------------------------------
+
+    def is_IOArray1_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOArray1(self):
+        try:
+            self.ioarray1 = [10,20,30,40]
+            return self.ioarray1
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def IOTrigPoll(self,in_data):
+        print "In IOTrigPoll command"
+        U = PyTango.Util.instance()
+        U.trigger_cmd_polling(self,in_data)
+
+#------------------------------------------------------------------
+
+    def IOAttrTrigPoll(self,in_data):
+        print "In IOAttrTrigPoll command"
+        U = PyTango.Util.instance()
+        U.trigger_attr_polling(self,in_data)
+
+#------------------------------------------------------------------
+
+    def IOShortSleep(self,in_data):
+        time.sleep(in_data[1])
+        return in_data[0] * 2
+
+#------------------------------------------------------------------
+
+    def IOSleepExcept(self,in_data):
+        time.sleep(in_data)
+        PyTango.Except.throw_exception("aaa","This is a test ","IOSleepExcept::execute()")
+
+#------------------------------------------------------------------
+
+    def IOAttrThrowEx(self,in_data):
+        if (in_data[0] == 0):
+            if (in_data[1] == 0):
+                self.Short_attr_except = False
+            else:
+                self.Short_attr_except = True
+        elif (in_data[0] == 1):
+            if (in_data[1] == 0):
+                self.event_change_attr_except = False
+            else:
+                self.event_change_attr_except = True
+        elif (in_data[0] == 2):
+            if (in_data[1] == 0):
+                self.event_quality_attr_except = False
+            else:
+                self.event_quality_attr_except = True
+        elif (in_data[0] == 3):
+            if (in_data[1] == 0):
+                self.event_throw_out_of_sync = False
+            else:
+                self.event_throw_out_of_sync = True
+
+#------------------------------------------------------------------
+
+    def IOAddOneElt(self):
+        self.attr_event_size += 1
+
+#------------------------------------------------------------------
+
+    def IORemoveOneElt(self):
+        self.attr_event_size -= 1
+
+#------------------------------------------------------------------
+
+    def IOIncValue(self):
+        self.attr_event[2] += 1
+
+#------------------------------------------------------------------
+
+    def IODecValue(self):
+        self.attr_event[2] -= 1
+
+#------------------------------------------------------------------
+
+    def IOChangeQuality(self,in_data):
+        if (in_data == 0):
+            self.attr_event_qua = PyTango.AttrQuality.ATTR_VALID
+        elif (in_data == 1):
+            self.attr_event_qua = PyTango.AttrQuality.ATTR_INVALID
+        elif (in_data == 2):
+            self.attr_event_qua = PyTango.AttrQuality.ATTR_ALARM
+        elif (in_data == 3):
+            self.attr_event_qua = PyTango.AttrQuality.ATTR_CHANGING
+
+#------------------------------------------------------------------
+
+    def IOPushEvent(self):
+        print "[DevTest::IOPushEvent] received"
+#        ex = ({'reason':"Pourqoi pas",'desc':"N'importe quoi",'origin':'ici','severity':'ERROR'})
+#        self.push_event("event_change_tst",ex)
+        self.push_event("event_change_tst",self.attr_event,self.attr_event_size)
+
+#------------------------------------------------------------------
+
+    def is_IOLong64_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOLong64(self,in_data):
+        print "[IOLong64::execute] received number",in_data," type = ",type(in_data)
+        in_data = in_data * 2;
+        print "[IOLong64::execute] return number",in_data
+        return in_data;
+
+#------------------------------------------------------------------
+
+    def is_IOULong64_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOULong64(self,in_data):
+        print "[IOULong64::execute] received number",in_data," type = ",type(in_data)
+        in_data = in_data * 2;
+        print "[IOULong64::execute] return number",in_data
+        return in_data;
+
+#------------------------------------------------------------------
+
+    def is_IOLong64Array_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOLong64Array(self,in_data):
+        l = range(len(in_data));
+        for i in l:
+            print "[IOLong64Array::execute] received number",in_data[i]
+            in_data[i] = in_data[i] * 2
+            print "[IOLong64Array::execute] return number",in_data[i]
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IOULong64Array_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOULong64Array(self,in_data):
+        l = range(len(in_data));
+        for i in l:
+            print "[IOULong64Array::execute] received number",in_data[i]
+            in_data[i] = in_data[i] * 2
+            print "[IOULong64Array::execute] return number",in_data[i]
+        return in_data
+
+#------------------------------------------------------------------
+
+#    def IOChangeStatus(self):
+#        print "[DevTest::IOChangeStatus] received"
+#        sta = self.get_status()
+#        print "Status =",sta
+#        sta = sta + "Hola, que tal ?"
+#        self.set_status(sta)
+
+#------------------------------------------------------------------
+
+    def is_IOSleep_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOSleep(self,in_data):
+        print "[IOSleep::execute] sleeping time ",in_data
+        time.sleep(in_data)
+
+#------------------------------------------------------------------
+
+    def is_IOArray2_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOArray2(self):
+        try:
+            self.attr_short_array = [100,200]
+            return self.attr_short_array
+
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def is_IOStrArray_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOStrArray(self):
+        dev_string_array = ['First string from dev_string_array','Second string from dev_string_array']
+        return dev_string_array
+
+#------------------------------------------------------------------
+
+    def is_IOStruct_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOStruct(self):
+        dev_struct = [[1000,2000],['First string from dev_struct','Second string from dev_struct']]
+        return dev_struct
+
+#------------------------------------------------------------------
+
+    def is_IORemoveAttribute_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IORemoveAttribute(self):
+        try:
+            print( '[IORemoveAttribute::execute] ')
+            self.remove_attribute('Added_short_attr')
+        
+        except PyTango.DevFailed,e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def is_IOSeqVecChar_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOSeqVecChar(self,in_data):
+        print('[IOSeqVecChar::execute] ' + str(len(in_data)) + ' elt(s) in temp vector')
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IOSeqVecShort_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOSeqVecShort(self,in_data):
+        print('[IOSeqVecShort::execute] ' + str(len(in_data)) + ' elt(s) in temp vector')
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IOSeqVecLong_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOSeqVecLong(self,in_data):
+        print('[IOSeqVecLong::execute] ' + str(len(in_data)) + ' elt(s) in temp vector')
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IOSeqVecFloat_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOSeqVecFloat(self,in_data):
+        print('[IOSeqVecFloat::execute] ' + str(len(in_data)) + ' elt(s) in temp vector')
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IOSeqVecDouble_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOSeqVecDouble(self,in_data):
+        print('[IOSeqVecDouble::execute] ' + str(len(in_data)) + ' elt(s) in temp vector')
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IOSeqVecUShort_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOSeqVecUShort(self,in_data):
+        print('[IOSeqVecUShort::execute] ' + str(len(in_data)) + ' elt(s) in temp vector')
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IOSeqVecULong_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOSeqVecULong(self,in_data):
+        print('[IOSeqVecULong::execute] ' + str(len(in_data)) + ' elt(s) in temp vector')
+        return in_data
+
+#------------------------------------------------------------------
+
+    def is_IOSeqVecString_allowed(self):
+        if (self.get_state() == PyTango.DevState.ON):
+            return True
+        else:
+            return False
+
+    def IOSeqVecString(self,in_data):
+        print('[IOSeqVecString::execute] ' + str(len(in_data)) + ' elt(s) in temp vector')
+        return in_data
+
+#------------------------------------------------------------------
+
+    def IOExit(self):
+        os._exit(0)
+
+#------------------------------------------------------------------
+
+    def IOPushDevEncodedEvent(self):
+        try:
+            print('[DevTest::IOPushDevEncodedEvent] received ')
+            self.push_event('Encoded_attr','','',*self.enc_attr)
+            
+        except PyTango.DevFailed as e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def IOSubscribeEvent(self):
+        try:
+            print('[DevTest::IOSubscribeEvent] received ')
+            if self.remote_dev is None:
+                devName = self.get_name()
+                newName =  devName[:devName.rfind('/')] + '/20'
+                self.remote_dev = PyTango.DeviceProxy(newName)
+            attr_name = 'short_attr'
+            self.cb.cb_executed = 0
+            self.remote_dev.poll_attribute(attr_name, 1000)
+            self.eve_id = self.remote_dev.subscribe_event(attr_name, PyTango.EventType.PERIODIC_EVENT,self.cb)
+        
+        except PyTango.DevFailed as e:
+            PyTango.Except.print_exception(e)
+            raise
+#        U = PyTango.Util.instance()
+#        devList = U.get_device_list_by_class('Starter')
+
+#------------------------------------------------------------------
+
+    def IOUnSubscribeEvent(self):
+        try:
+            print('[DevTest::IOUnSubscribeEvent] received ')
+            if self.eve_id != 0:
+                self.remote_dev.unsubscribe_event(self.eve_id)
+                self.remote_dev.stop_poll_attribute('short_attr')
+        
+        except PyTango.DevFailed as e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def IOGetCbExecuted(self):
+        print('[IOGetCbExecuted::execute] received number ')
+        return self.cb.cb_executed
+
+#------------------------------------------------------------------
+
+    def is_OLong_allowed(self):
+        if self.get_state() == PyTango.DevState.ON:
+            return True
+        else:
+            return False
+        
+    def OLong(self):
+        theNumber = 22
+        print('[OLong::execute] return number ' + str(theNumber)) 
+        return theNumber
+
+#------------------------------------------------------------------
+
+    def is_OULong_allowed(self):
+        if self.get_state() == PyTango.DevState.ON:
+            return True
+        else:
+            return False
+        
+    def OULong(self):
+        theNumber = 333
+        print('[OULong::execute] return number ' + str(theNumber)) 
+        return theNumber
+
+#------------------------------------------------------------------
+
+    def is_OLongArray_allowed(self):
+        if self.get_state() == PyTango.DevState.ON:
+            return True
+        else:
+            return False
+        
+    def OLongArray(self):
+        theReturnedArray = range(555,559)
+        for i in theReturnedArray:
+            print('[OLongArray::execute] return number ' + str(i)) 
+        return theReturnedArray
+
+#------------------------------------------------------------------
+
+    def is_OULongArray_allowed(self):
+        if self.get_state() == PyTango.DevState.ON:
+            return True
+        else:
+            return False
+        
+    def OULongArray(self):
+        theReturnedArray = range(777,780)
+        for i in theReturnedArray:
+            print('[OULongArray::execute] return number ' + str(i)) 
+        return theReturnedArray
+
+#------------------------------------------------------------------
+
+    def is_OLongString_allowed(self):
+        if self.get_state() == PyTango.DevState.ON:
+            return True
+        else:
+            return False
+        
+    def OLongString(self):
+        lvalue = range(999,1005)
+        svalue = ['Hola todos'] * 1
+        theReturned = (lvalue,svalue)
+        for i in lvalue:
+            print('[OLongString::execute] return number ' + str(i))
+        for i in svalue:
+            print('[OLongString::execute] return string ' + str(i))
+        return theReturned
+
+#------------------------------------------------------------------
+
+    def GetLongSize(self):
+        size = 32
+        if PyTango.constants.TANGO_LONG64 == True:
+            size = 64
+        return size
+
+#------------------------------------------------------------------
+
+    def IOSetWAttrLimit(self,in_data):
+        try:
+            w_attr = self.get_device_attr().get_w_attr_by_name('Double_attr_w')
+            limit = in_data[1]
+            if in_data[0] == 0.0:
+                w_attr.set_min_value(limit)
+            else:
+                w_attr.set_max_value(limit)
+                
+        except PyTango.DevFailed as e:
+            PyTango.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def ChangeEncodedFormat(self):
+        if self.enc_format_toggle == False:
+            self.enc_attr[0] = 'This format'
+            self.enc_format_toggle = True
+        else:
+            self.enc_attr[0] = 'Another format'
+            self.enc_format_toggle = False
+            
+#------------------------------------------------------------------
+
+    def ChangeEncodedData(self):
+        data = bytearray(self.enc_attr[1])
+        data[2] += 1
+        self.enc_attr[1] = data
+#        self.enc_attr[1][2] = chr(ord(self.enc_attr[1][2]) + 1).encode('utf-8')
+            
+#------------------------------------------------------------------
+
+    def PushDataReady(self,in_data):
+        try:
+            print('Pushing Data Ready event for attribute ' + in_data[1][0])
+            self.push_data_ready_event(in_data[1][0],in_data[0][0])
+            
+        except PyTango.DevFailed as e:
+            PyTagno.Except.print_exception(e)    
+            
+#------------------------------------------------------------------
+
+    def SubDeviceThread(self):
+        try:
+            tg = PyTango.Util.instance()
+            deviceList = tg.get_device_list_by_class('DevTest')
+            if len(deviceList) > 1:
+                deviceList = sorted([device.get_name() for device in deviceList])
+                # choose the 2nd device as a Sub Device
+                print('Thread : Connect device = ' + deviceList[1])
+                remote_device = PyTango.DeviceProxy(deviceList[1])
+                
+        except PyTango.DevFailed:
+            pass
+        
+
+    def SubDeviceTst(self):
+        try:
+            t = threading.Thread(target=self.SubDeviceThread)
+            t.start()
+            
+            connected = False
+            tg = PyTango.Util.instance()
+            deviceList = tg.get_device_list_by_class('DevTest')
+            if len(deviceList) > 2:
+                deviceList = sorted([device.get_name() for device in deviceList])
+                # choose the 3rd device as a Sub Device
+                remote_device = PyTango.DeviceProxy(deviceList[2])
+                connected = True
+            return connected
+                
+        except PyTango.DevFailed as e:
+            PyTagno.Except.print_exception(e)
+            raise
+            
+#------------------------------------------------------------------
+
+    def is_IOEncoded_allowed(self):
+        if self.get_state() == PyTango.DevState.ON:
+            return True
+        else:
+            return False
+
+    def IOEncoded(self,in_data):
+        try:
+            print('[IOEncoded::execute] received string ' + in_data[0])
+            data = bytearray()
+            for nb in bytearray(in_data[1]):
+                print('[IOEncoded::execute] received number ' + str(nb))
+                data += chr(nb*2)
+                print('[IOEncoded::execute] returned number ' + str(data[-1]))
+            return ['Returned string', data]
+                
+        except PyTango.DevFailed as e:
+            PyTagno.Except.print_exception(e)
+            raise
+            
+#------------------------------------------------------------------
+
+    def is_OEncoded_allowed(self):
+        if self.get_state() == PyTango.DevState.ON:
+            return True
+        else:
+            return False
+
+    def OEncoded(self):
+        self.encoded_cmd_ctr += 1
+        if self.encoded_cmd_ctr % 2 == 0:
+            data = bytearray([11,21])
+            theReturned = ['Odd - OEncoded format',data]
+        else:
+            data = bytearray([10,20,30,40])
+            theReturned = ['Even - OEncoded format',data]
+        return theReturned
+            
+#------------------------------------------------------------------
+
+    def is_SetGetAlarms_allowed(self):
+        if self.get_state() == PyTango.DevState.ON:
+            return True
+        else:
+            return False
+        
+    def _setAlarms(self,name,min_alarm,min_warning,max_warning,max_alarm,result):
+        attr = self.get_device_attr().get_attr_by_name(name)
+        conf = attr.get_properties_3()
+            
+        try:
+            attr.set_min_alarm(min_alarm)
+            attr.set_min_warning(min_warning)
+            attr.set_max_warning(max_warning)
+            attr.set_max_alarm(max_alarm)
+            
+            result.append(attr.get_name())
+            result.append(str(attr.get_min_alarm()))
+            result.append(str(attr.get_min_warning()))
+            result.append(str(attr.get_max_warning()))
+            result.append(str(attr.get_max_alarm()))
+            
+            attr.set_upd_properties(conf)
+        
+        except PyTango.DevFailed as e:
+            attr.set_upd_properties(conf)
+            raise
+    
+    def SetGetAlarms(self):
+        try:
+            print('[SetGetAlarms::execute]')
+            alarmsReturn = []
+            self._setAlarms('Double_attr',-999.99,-888.88,888.88,999.99,alarmsReturn)
+            self._setAlarms('Float_attr',-777.77,-666.66,666.66,777.77,alarmsReturn)
+            self._setAlarms('Long_attr',1000,1100,1400,1500,alarmsReturn)
+            self._setAlarms('Long64_attr',-90000,-80000,80000,90000,alarmsReturn)
+            self._setAlarms('Short_attr',-5000,-4000,4000,5000,alarmsReturn)
+            self._setAlarms('UChar_attr',1,2,230,240,alarmsReturn)
+            self._setAlarms('ULong_attr',1,2,666666,777777,alarmsReturn)
+            self._setAlarms('ULong64_attr',1,2,77777777,88888888,alarmsReturn)
+            self._setAlarms('UShort_attr',1,2,20000,30000,alarmsReturn)
+            return alarmsReturn
+        
+        except PyTango.DevFailed as e:
+            print('Exception while setting alarms')
+            PyTango.Except.print_exception(e)
+            raise
+            
+#------------------------------------------------------------------
+
+    def is_SetGetRanges_allowed(self):
+        if self.get_state() == PyTango.DevState.ON:
+            return True
+        else:
+            return False
+        
+    def _setRanges(self,name,min_value,max_value,result):
+        wattr = self.get_device_attr().get_attr_by_name(name)
+        conf = wattr.get_properties_3()
+            
+        try:
+            wattr.set_min_value(min_value)
+            wattr.set_max_value(max_value)
+            
+            result.append(wattr.get_name())
+            result.append(str(wattr.get_min_value()))
+            result.append(str(wattr.get_max_value()))
+            
+            wattr.set_upd_properties(conf)
+        
+        except PyTango.DevFailed as e:
+            wattr.set_upd_properties(conf)
+            raise
+    
+    def SetGetRanges(self):
+        try:
+            print('[SetGetRanges::execute]')
+            rangesReturn = []
+            self._setRanges('Double_attr_w',-1111.11,1111.11,rangesReturn)
+            self._setRanges('Float_attr_w',-888.88,888.88,rangesReturn)
+            self._setRanges('Long_attr_w',900,1600,rangesReturn)
+            self._setRanges('Long64_attr_rw',-100000,100000,rangesReturn)
+            self._setRanges('Short_attr_w',-6000,6000,rangesReturn)
+            self._setRanges('UChar_attr_w',0,250,rangesReturn)
+            self._setRanges('ULong_attr_rw',0,888888,rangesReturn)
+            self._setRanges('ULong64_attr_rw',0,99999999,rangesReturn)
+            self._setRanges('UShort_attr_w',0,40000,rangesReturn)
+            return rangesReturn
+        
+        except PyTango.DevFailed as e:
+            print('Exception while setting ranges')
+            PyTango.Except.print_exception(e)
+            raise
+            
+#------------------------------------------------------------------
+
+    def IOPollingInDevice(self):
+        try:
+            ret = []
+            att_name = 'Double_spec_attr'
+            cmd_name = 'OULong'
+            
+            # is_xxx_polled()
+            ss = 'Attribute ' + att_name + ' polled = '
+            if self.is_attribute_polled(att_name) == True:
+                ss += 'true'
+            else:
+                ss += 'false'
+            ret.append(ss)
+            ss = 'Command ' + cmd_name + ' polled = '
+            if self.is_command_polled(cmd_name) == True:
+                ss += 'true'
+            else:
+                ss += 'false'
+            ret.append(ss)
+            
+            # get_xxx_poll_period()
+            ss = 'Attribute ' + att_name + ' polling period = ' + str(self.get_attribute_poll_period(att_name))
+            ret.append(ss)
+            ss = 'Command ' + cmd_name + ' polling period = ' + str(self.get_command_poll_period(cmd_name))
+            ret.append(ss)
+            
+            # poll_xxx()
+            self.poll_attribute(att_name,250)
+            self.poll_command(cmd_name,250)
+            time.sleep(1)
+            
+            # is_xxx_polled()
+            ss = 'Attribute ' + att_name + ' polled = '
+            if self.is_attribute_polled(att_name) == True:
+                ss += 'true'
+            else:
+                ss += 'false'
+            ret.append(ss)
+            ss = 'Command ' + cmd_name + ' polled = '
+            if self.is_command_polled(cmd_name) == True:
+                ss += 'true'
+            else:
+                ss += 'false'
+            ret.append(ss)
+            
+            # get_xxx_poll_period()
+            ss = 'Attribute ' + att_name + ' polling period = ' + str(self.get_attribute_poll_period(att_name))
+            ret.append(ss)
+            ss = 'Command ' + cmd_name + ' polling period = ' + str(self.get_command_poll_period(cmd_name))
+            ret.append(ss)
+            
+            # stop_poll_xxx()
+            self.stop_poll_attribute(att_name)
+            self.stop_poll_command(cmd_name)
+            time.sleep(1)
+            
+            # is_xxx_polled()
+            ss = 'Attribute ' + att_name + ' polled = '
+            if self.is_attribute_polled(att_name) == True:
+                ss += 'true'
+            else:
+                ss += 'false'
+            ret.append(ss)
+            ss = 'Command ' + cmd_name + ' polled = '
+            if self.is_command_polled(cmd_name) == True:
+                ss += 'true'
+            else:
+                ss += 'false'
+            ret.append(ss)
+            
+            # get_xxx_poll_period()
+            ss = 'Attribute ' + att_name + ' polling period = ' + str(self.get_attribute_poll_period(att_name))
+            ret.append(ss)
+            ss = 'Command ' + cmd_name + ' polling period = ' + str(self.get_command_poll_period(cmd_name))
+            ret.append(ss)
+                
+            return ret
+        
+        except PyTango.DevFailed as e:
+            PyTango.Except.print_exception(e)
+            raise
+            
+#------------------------------------------------------------------
+
+
+
+
+
+
+#------------------------------------------------------------------
+#------------------------------------------------------------------
+#
+#                READING THE ATTRIBUTES
+#
+#------------------------------------------------------------------
+#------------------------------------------------------------------
+
+
+
+    def read_attr_hardware(self,data):
+        print 'In read_attr_hardware'
+
+#------------------------------------------------------------------
+
+    def read_Short_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Short_attr"
+        self.attr_short = 12;
+        if (self.Short_attr_except == False):
+            the_att.set_value(self.attr_short)
+        else:
+            PyTango.Except.throw_exception("aaa","This is a test","DevTest::read_attr")
+
+#------------------------------------------------------------------
+
+    def read_Long_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Long_attr"
+        the_att.set_value(self.attr_long)
+
+#------------------------------------------------------------------
+
+    def read_Double_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Double_attr"
+        self.attr_double = 3.2;
+        the_att.set_value(self.attr_double)
+
+#------------------------------------------------------------------
+
+    def read_String_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name String_attr"
+        the_att.set_value("test_string");
+
+#------------------------------------------------------------------
+
+    def read_Short_spec_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Short_spec_attr"
+        self.attr_short_array = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
+
+        self.attr_short_array[0] = 10
+        self.attr_short_array[1] = 20
+        self.attr_short_array[2] = 30
+        self.attr_short_array[3] = 40
+        the_att.set_value(self.attr_short_array,4)
+
+#------------------------------------------------------------------
+
+    def read_Long_spec_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Long_spec_attr"
+        self.attr_long_array[0] = 0
+        self.attr_long_array[1] = 1
+        self.attr_long_array[2] = 2
+        self.attr_long_array[3] = 3
+        self.attr_long_array[4] = 4
+        self.attr_long_array[5] = 5
+        self.attr_long_array[6] = 6
+        self.attr_long_array[7] = 7
+        self.attr_long_array[8] = 8
+        self.attr_long_array[9] = 9
+        the_att.set_value(self.attr_long_array,10)
+
+#------------------------------------------------------------------
+
+    def read_Double_spec_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Double_spec_attr"
+        self.attr_db_array[0] = 1.11
+        self.attr_db_array[1] = 2.22
+        the_att.set_value(self.attr_db_array,2)
+
+#------------------------------------------------------------------
+
+    def read_String_spec_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name String_spec_attr"
+        self.attr_str_array = ['Hello world','Hello universe']
+        the_att.set_value(self.attr_str_array,2)
+
+#------------------------------------------------------------------
+
+    def read_Short_ima_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Short_ima_attr"
+        self.attr_short_array_1 = [40,60,80,100]
+        the_att.set_value(self.attr_short_array_1,2,2)
+
+#------------------------------------------------------------------
+
+    def read_Long_ima_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Long_ima_attr"
+        self.attr_long_array = [0,1,2,3,4,5]
+        the_att.set_value(self.attr_long_array,3,2)
+
+#------------------------------------------------------------------
+
+    def read_Double_ima_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Double_ima_attr"
+        self.attr_db_array = [5.55,6.66]
+        the_att.set_value(self.attr_db_array,2,1)
+
+#------------------------------------------------------------------
+
+    def read_String_ima_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name String_ima_attr"
+        self.attr_str_array = ["Hello milky way","Hello moon"]
+        the_att.set_value(self.attr_str_array,1,2)
+
+#------------------------------------------------------------------
+
+    def read_attr_dq_sh(self,the_att):
+        print "[DevTest::read_attr] attribute name attr_dq_sh"
+        self.attr_dq_short = 77;
+        the_att.set_value_date_quality(self.attr_dq_short,time.time(),PyTango.AttrQuality.ATTR_VALID);
+
+#------------------------------------------------------------------
+
+    def read_attr_dq_lo(self,the_att):
+        print "[DevTest::read_attr] attribute name attr_dq_lo"
+        self.attr_dq_long = 7777;
+        the_att.set_value_date_quality(self.attr_dq_long,time.time(),PyTango.AttrQuality.ATTR_ALARM);
+
+#------------------------------------------------------------------
+
+    def read_attr_dq_db(self,the_att):
+        print "[DevTest::read_attr] attribute name attr_dq_db"
+        self.attr_dq_double = 8.888;
+        the_att.set_value_date_quality(self.attr_dq_double,time.time(),PyTango.AttrQuality.ATTR_VALID);
+
+#------------------------------------------------------------------
+
+    def read_attr_dq_str(self,the_att):
+        print "[DevTest::read_attr] attribute name attr_dq_str"
+        self.attr_dq_str = 'Setting value date and quality'
+        the_att.set_value_date_quality(self.attr_dq_str,time.time(),PyTango.AttrQuality.ATTR_ALARM);
+
+#------------------------------------------------------------------
+
+    def read_attr_no_data(self,the_att):
+        print "[DevTest::read_attr] attribute name attr_no_data"
+        the_att.set_quality(PyTango.AttrQuality.ATTR_VALID);
+
+#------------------------------------------------------------------
+
+    def read_attr_wrong_type(self,the_att):
+        print "[DevTest::read_attr] attribute name attr_wrong_type"
+        self.attr_long = 1246;
+        the_att.set_value(self.attr_long);
+
+#------------------------------------------------------------------
+
+    def read_attr_wrong_size(self,the_att):
+        print "[DevTest::read_attr] attribute name attr_wrong_size"
+        the_att.set_value(self.attr_long_array,1000,1000);
+
+#------------------------------------------------------------------
+
+    def read_attr_no_alarm(self,the_att):
+        print "[DevTest::read_attr] attribute name attr_no_alarm"
+        self.attr_long = 1246;
+        the_att.check_alarm();
+        the_att.set_value(self.attr_long)
+
+#------------------------------------------------------------------
+
+    def read_Long_attr_with_w(self,the_att):
+        print "[DevTest::read_attr] attribute name Long_attr_with_w"
+        self.attr_long = 1246;
+        the_att.set_value(self.attr_long)
+
+#------------------------------------------------------------------
+
+    def read_Long_attr_with_w2(self,the_att):
+        print "[DevTest::read_attr] attribute name Long_attr_with_w2"
+        the_att.set_value(self.attr_long_rw2)
+
+#------------------------------------------------------------------
+
+    def read_Short_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name Short_attr_rw"
+        the_att.set_value(self.attr_short_rw)
+
+#------------------------------------------------------------------
+
+    def read_Float_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Float_attr"
+        the_att.set_value(4.5)
+
+#------------------------------------------------------------------
+
+    def read_Boolean_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Boolean_attr"
+        the_att.set_value(True)
+
+#------------------------------------------------------------------
+
+    def read_UShort_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name UShort_attr"
+        the_att.set_value(111)
+
+#------------------------------------------------------------------
+
+    def read_UChar_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name UChar_attr"
+        the_att.set_value(88)
+
+#------------------------------------------------------------------
+
+    def read_Float_spec_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Float_spec_attr"
+        self.attr_spec_float = [4.5,8.5,16.5]
+        the_att.set_value(self.attr_spec_float)
+
+#------------------------------------------------------------------
+
+    def read_Boolean_spec_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Boolean_spec_attr"
+        self.attr_spec_boolean = [True,True,False,True,True]
+        the_att.set_value(self.attr_spec_boolean)
+
+#------------------------------------------------------------------
+
+    def read_UShort_spec_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name UShort_spec_attr"
+        self.attr_spec_ushort = [333,444]
+        the_att.set_value(self.attr_spec_ushort)
+
+#------------------------------------------------------------------
+
+    def read_UChar_spec_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name UChar_spec_attr"
+        self.attr_spec_uchar = [28,45,156,34,200,12]
+        the_att.set_value(self.attr_spec_uchar)
+
+#------------------------------------------------------------------
+
+    def read_PollLong_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name PollLong_attr"
+        self.PollLong_attr_num += 1
+        if ((self.PollLong_attr_num % 2) == 0):
+            self.Poll_attr_long = 5555
+        else:
+            self.Poll_attr_long = 6666
+        the_att.set_value(self.Poll_attr_long)
+
+#------------------------------------------------------------------
+
+    def read_PollString_spec_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name PollString_spec_attr"
+        self.PollString_spec_attr_num += 1
+        if ((self.PollString_spec_attr_num % 2) == 0):
+            self.attr_str_array = ["Hello world","Hello universe"]
+        else:
+            self.attr_str_array = ["Hello Grenoble","Hello Paris"]
+        the_att.set_value(self.attr_str_array)
+
+#------------------------------------------------------------------
+
+    def read_Short_spec_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name Short_spec_attr_rw"
+        self.short_spec_attr = [8,9]
+        the_att.set_value(self.short_spec_attr)
+
+#------------------------------------------------------------------
+
+    def read_String_spec_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name Short_spec_attr_rw"
+        self.string_spec_attr = ["Thank's god","It's friday"]
+        the_att.set_value(self.string_spec_attr)
+
+#------------------------------------------------------------------
+
+    def read_Float_spec_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name Float_spec_attr_rw"
+        self.attr_spec_float = [5.5,11.5]
+        the_att.set_value(self.attr_spec_float)
+
+#------------------------------------------------------------------
+
+    def read_UChar_spec_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name UChar_spec_attr_rw"
+        self.attr_spec_uchar = [22,44,66]
+        the_att.set_value(self.attr_spec_uchar)
+
+#------------------------------------------------------------------
+
+    def read_Short_ima_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name Short_ima_attr_rw"
+        self.short_ima_attr = [6,7,8,9]
+        the_att.set_value(self.short_ima_attr,2,2)
+
+#------------------------------------------------------------------
+
+    def read_String_ima_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name String_ima_attr_rw"
+        self.string_ima_attr = ["Alors la, pour une surprise","c'est une surprise"]
+        the_att.set_value(self.string_ima_attr,2,1)
+
+#------------------------------------------------------------------
+
+    def read_Boolean_ima_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name Boolean_ima_attr_rw"
+        self.attr_spec_boolean = [True,False]
+        the_att.set_value(self.attr_spec_boolean,2,1)
+
+#------------------------------------------------------------------
+
+    def read_UShort_ima_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name UShort_ima_attr_rw"
+        self.attr_spec_ushort = [2,3]
+        the_att.set_value(self.attr_spec_ushort,2,1)
+
+#------------------------------------------------------------------
+
+    def read_Poll_buff(self,the_att):
+        print "[DevTest::read_attr] attribute name Poll_buff"
+
+#------------------------------------------------------------------
+
+    def read_Poll_buffRW(self,the_att):
+        print "[DevTest::read_attr] attribute name Poll_buffRW"
+
+#------------------------------------------------------------------
+
+    def read_attr_asyn(self,the_att):
+        print "[DevTest::read_attr] attribute name attr_asyn"
+        time.sleep(2)
+        the_att.set_value(5.55)
+        print "Leaving reading attr_asyn attribute"
+
+#------------------------------------------------------------------
+
+    def read_attr_asyn_to(self,the_att):
+        print "[DevTest::read_attr] attribute name attr_asyn_to"
+        time.sleep(4)
+        the_att.set_value(5.55)
+        print "Leaving reading attr_asyn_to attribute"
+
+#------------------------------------------------------------------
+
+    def read_attr_asyn_except(self,the_att):
+        print "[DevTest::read_attr] attribute name attr_asyn_except"
+        time.sleep(2)
+        print "Leaving reading attr_asyn_except attribute"
+        PyTango.Except.throw_exception("aaa","This is a test ","DevTest::read_attr")
+
+#------------------------------------------------------------------
+
+    def read_event_change_tst(self,the_att):
+        print "[DevTest::read_attr] attribute name event_change_tst"
+        if (self.event_change_attr_except == False):
+            if self.event_throw_out_of_sync == True:
+                time.sleep(0.4)
+            the_att.set_value(self.attr_event,self.attr_event_size)
+        else:
+            PyTango.Except.throw_exception("bbb","This is a test ","DevTest::read_attr")
+
+#------------------------------------------------------------------
+
+    def read_event64_change_tst(self,the_att):
+        print "[DevTest::read_attr] attribute name event64_change_tst"
+        if (self.event_change_attr_except == False):
+            the_att.set_value(self.attr_event64,self.attr_event64_size)
+        else:
+            PyTango.Except.throw_exception("bbb64","This is a test ","DevTest::read_attr")
+
+#------------------------------------------------------------------
+
+    def read_event_quality_tst(self,the_att):
+        print "[DevTest::read_attr] attribute name event_quality_tst"
+        if (self.event_quality_attr_except == False):
+            if (self.attr_event_qua != PyTango.AttrQuality.ATTR_INVALID):
+                the_att.set_value(self.attr_qua_event,2)
+                the_att.set_quality(self.attr_event_qua)
+        else:
+            PyTango.Except.throw_exception("ccc","This is a test ","DevTest::read_attr")
+
+
+#------------------------------------------------------------------
+
+    def read_slow_actuator(self,the_att):
+        print "[DevTest::read_attr] attribute name slow_actuator"
+        self.slow_actua += 1
+        the_att.set_value(self.slow_actua)
+        ti = time.time()
+        if (self.slow_actua_write != 0):
+            delta = ti - self.slow_actua_write
+            if (delta >= 3):
+                the_att.set_quality(PyTango.AttrQuality.ATTR_VALID)
+                self.slow_actua_write = 0
+
+#------------------------------------------------------------------
+
+    def read_fast_actuator(self,the_att):
+        print "[DevTest::read_attr] attribute name fast_actuator"
+        the_att.set_value(self.fast_actua)
+
+#------------------------------------------------------------------
+
+    def read_Long64_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Long64_attr"
+        the_att.set_value(9223372036854775807)
+
+#------------------------------------------------------------------
+
+    def read_Long64_spec_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Long64_spec_attr"
+        attr_long64_array = [ 0, -9223372036854775808, 9223372036854775807, 0 ]
+        the_att.set_value(attr_long64_array,4)
+
+#------------------------------------------------------------------
+
+    def read_Long64_ima_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Long64_ima_attr"
+        attr_long64_array = [0, -9223372036854775808, 9223372036854775807, 0, 0, -9223372036854775808, 9223372036854775807, 0]
+        the_att.set_value(attr_long64_array,4,2)
+
+#------------------------------------------------------------------
+
+    def read_Long64_attr_w(self,the_att):
+        print "[DevTest::read_attr] attribute name Long64_attr_w"
+        the_att.set_value(9223372036854775807)
+
+#------------------------------------------------------------------
+
+    def read_Long64_spec_attr_w(self,the_att):
+        print "[DevTest::read_attr] attribute name Long64_spec_attr_w"
+        attr_long64_array = [ 0, -9223372036854775808, 9223372036854775807, 0 ]
+        the_att.set_value(attr_long64_array,4)
+
+#------------------------------------------------------------------
+
+    def read_Long64_ima_attr_w(self,the_att):
+        print "[DevTest::read_attr] attribute name Long64_ima_attr_w"
+        attr_long64_array = [0, -9223372036854775808, 9223372036854775807, 0, 0, -9223372036854775808, 9223372036854775807, 0]
+        the_att.set_value(attr_long64_array,4,2)
+
+#------------------------------------------------------------------
+
+    def read_Long64_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name Long64_attr_rw"
+        the_att.set_value(9223372036854775807)
+
+#------------------------------------------------------------------
+
+    def read_Long64_spec_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name Long64_spec_attr_rw"
+        attr_long64_array = [ 0, -9223372036854775808, 9223372036854775807, 0 ]
+        the_att.set_value(attr_long64_array,4)
+
+#------------------------------------------------------------------
+
+    def read_Long64_ima_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name Long64_ima_attr_rw"
+        attr_long64_array = [0, -9223372036854775808, 9223372036854775807, 0, 0, -9223372036854775808, 9223372036854775807, 0]
+        the_att.set_value(attr_long64_array,4,2)
+
+#------------------------------------------------------------------
+
+    def read_Long_spec_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name Long_spec_attr_rw"
+        the_att.set_value(self.Long_spec_attr_rw)
+
+#------------------------------------------------------------------
+
+    def read_Encoded_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Encoded_attr_rw"
+        the_att.set_value(*self.enc_attr)
+
+#------------------------------------------------------------------
+
+    def read_ULong_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name ULong_attr"
+        # TODO: 'L' suffix no more supported in Python3
+        self.attr_ulong = 100L
+        the_att.set_value(self.attr_ulong)
+
+#------------------------------------------------------------------
+
+    def read_ULong64_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name ULong64_attr"
+        # TODO: 'L' suffix no more supported in Python3
+        self.attr_ulong64 = 200L
+        the_att.set_value(self.attr_ulong64)
+
+#------------------------------------------------------------------
+
+    def read_ULong_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name ULong_attr_rw"
+        the_att.set_value(self.attr_ulong_rw)
+
+#------------------------------------------------------------------
+
+    def read_ULong64_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name ULong64_attr_rw"
+        # TODO: long() no more supported in Python3
+        the_att.set_value(long(self.attr_ulong64_rw))
+
+#------------------------------------------------------------------
+
+    def read_State_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name State_attr_rw"
+        the_att.set_value(self.attr_state_rw)
+
+#------------------------------------------------------------------
+
+    def read_ULong_spec_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name ULong_spec_attr_rw"
+        the_att.set_value(self.attr_spec_ulong_rw,3)
+
+#------------------------------------------------------------------
+
+    def read_ULong64_spec_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name ULong64_spec_attr_rw"
+        # TODO: long() no more supported in Python3, as well as map (returns a pointer)
+        the_att.set_value(map(long,self.attr_spec_ulong64_rw),3)
+
+#------------------------------------------------------------------
+
+    def read_State_spec_attr_rw(self,the_att):
+        print "[DevTest::read_attr] attribute name State_spec_attr_rw"
+        the_att.set_value(self.attr_spec_state_rw,2)
+
+#------------------------------------------------------------------
+
+    def read_Sub_device_tst(self,the_att):
+        try:
+            print('[DevTest::read_attr] attribute name Sub_device_tst')
+            tg = PyTango.Util.instance()
+            deviceList = tg.get_device_list_by_class('DevTest')
+            if len(deviceList) > 1:
+                deviceList = sorted([device.get_name() for device in deviceList])
+                try:
+                    remote_dev = PyTango.DeviceProxy(deviceList[1])
+                    self.attr_sub_device_tst = True
+                except:
+                    self.attr_sub_device_tst = False
+            else:
+                self.attr_sub_device_tst = False
+            the_att.set_value(self.attr_sub_device_tst)
+        
+        except PyTango.DevFailed as e:
+            PyTagno.Except.print_exception(e)
+            raise
+
+#------------------------------------------------------------------
+
+    def read_SlowAttr(self,the_att):
+        time.sleep(0.5)
+        the_att.set_value(self.attr_slow)
+
+#------------------------------------------------------------------
+
+    def read_Encoded_image(self,the_att):
+        print('[DevTest::read_attr] attribute name Encoded_attr_image')
+        self.jpeg = PyTango.EncodedAttribute()
+        imageData = bytearray(256*256)
+        for i in range(0,256):
+            for j in range(0,256):
+                imageData[i+j*256] = i
+        imageData = bytes(imageData)
+        self.jpeg.encode_jpeg_gray8(imageData,256,256,50.0)
+        the_att.set_value(self.jpeg)
+
+#------------------------------------------------------------------
+
+    def read_DefAttr(self,the_att):
+        print('[DevTest::read_attr] attribute name DefAttr')
+        the_att.set_value(self.att_conf)
+
+#------------------------------------------------------------------
+
+    def read_DefUserAttr(self,the_att):
+        print('[DevTest::read_attr] attribute name DefUserAttr')
+        the_att.set_value(self.att_conf)
+
+#------------------------------------------------------------------
+
+    def read_DefClassAttr(self,the_att):
+        print('[DevTest::read_attr] attribute name DefClassAttr')
+        the_att.set_value(self.att_conf)
+
+#------------------------------------------------------------------
+
+    def read_DefClassUserAttr(self,the_att):
+        print('[DevTest::read_attr] attribute name DefClassUserAttr')
+        the_att.set_value(self.att_conf)
+
+#------------------------------------------------------------------
+
+    def read_DefUserAttr(self,the_att):
+        print('[DevTest::read_attr] attribute name DefUserAttr')
+        the_att.set_value(self.att_conf)
+
+#------------------------------------------------------------------
+#------------------------------------------------------------------
+#
+#                WRITING THE ATTRIBUTES
+#
+#------------------------------------------------------------------
+#------------------------------------------------------------------
+
+
+
+
+
+    def write_Short_attr_w(self,the_att):
+        data = []
+        the_att.get_write_value(data)
+
+#------------------------------------------------------------------
+
+    def write_Long_attr_w(self,the_att):
+        print "In write_Long_attr_w for attribute",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Float_attr_w(self,the_att):
+        print "In write_Float_attr_w for attribute",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_UShort_attr_w(self,the_att):
+        print "In write_UShort_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data;
+
+#------------------------------------------------------------------
+
+    def write_UChar_attr_w(self,the_att):
+        print "In write_UChar_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Short_attr_rw(self,the_att):
+        print "In write_Short_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        self.attr_short_rw = data[0]
+
+#------------------------------------------------------------------
+
+    def write_Long_attr_with_w(self,the_att):
+        print "In write_Long_attr_with_w for attribute ",the_att.get_name()
+
+#------------------------------------------------------------------
+
+    def write_Long_attr_with_w2(self,the_att):
+        print "In write_Long_attr_with_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        self.attr_long_rw2 = data[0]
+
+#------------------------------------------------------------------
+
+    def write_Short_attr_w2(self,the_att):
+        print "In write_Short_attr_w2 for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Double_attr_w(self,the_att):
+        print "In write_Double_attr_w for attribute ",the_att.get_name()
+        data=[];
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_String_attr_w2(self,the_att):
+        print "In write_String_attr_w2 for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_String_attr_w(self,the_att):
+        print "In write_String_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Boolean_attr_w(self,the_att):
+        print "In write_Boolean_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Short_spec_attr_w(self,the_att):
+        print "In write_Short_spec_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Short_ima_attr_w(self,the_att):
+        print "In write_Short_ima_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Long_spec_attr_w(self,the_att):
+        print "In write_Long_spec_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Double_spec_attr_w(self,the_att):
+        print "In write_Double_spec_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_String_spec_attr_w(self,the_att):
+        print "In write_String_spec_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Float_spec_attr_w(self,the_att):
+        print "In write_Float_spec_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Boolean_spec_attr_w(self,the_att):
+        print "In write_Boolean_spec_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_UShort_spec_attr_w(self,the_att):
+        print "In write_UShort_spec_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_UChar_spec_attr_w(self,the_att):
+        print "In write_UChar_spec_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_String_ima_attr_w(self,the_att):
+        print "In write_String_ima_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def is_write_Float_ima_attr_w(self,req_type):
+        return True
+
+    def write_Float_ima_attr_w(self,the_att):
+        print "In write_Float_ima_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_UShort_ima_attr_w(self,the_att):
+        print "In write_UShort_ima_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Short_spec_attr_rw(self,the_att):
+        print "In write_Short_spec_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_String_spec_attr_rw(self,the_att):
+        print "In write_String_spec_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Float_spec_attr_rw(self,the_att):
+        print "In write_Float_spec_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_UChar_spec_attr_rw(self,the_att):
+        print "In write_UChar_spec_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Short_ima_attr_rw(self,the_att):
+        print "In write_Short_ima_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_String_ima_attr_rw(self,the_att):
+        print "In write_String_ima_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Boolean_ima_attr_rw(self,the_att):
+        print "In write_Boolean_ima_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_UShort_ima_attr_rw(self,the_att):
+        print "In write_UShort_ima_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_attr_asyn_write(self,the_att):
+        print "In write_attr_asyn_write for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+        time.sleep(2)
+
+#------------------------------------------------------------------
+
+    def write_attr_asyn_write_to(self,the_att):
+        print "In write_attr_asyn_write_to for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+        time.sleep(4)
+
+#------------------------------------------------------------------
+
+    def write_attr_asyn_write_except(self,the_att):
+        print "In write_attr_asyn_write_except for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+        time.sleep(2)
+        PyTango.Except.throw_exception("aaa","This is a test ","DevTest::write_attr_hardware")
+
+#------------------------------------------------------------------
+
+    def write_slow_actuator(self,the_att):
+        print "In write_slow_actuator for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        self.slow_actua = data[0]
+        self.slow_actua_write = time.time()
+        the_att.set_value(self.slow_actua)
+        the_att.set_quality(PyTango.AttrQuality.ATTR_CHANGING)
+
+#------------------------------------------------------------------
+
+    def write_fast_actuator(self,the_att):
+        print "In write_fast_actuator for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        self.fast_actua = data[0]
+        the_att.set_value(self.fast_actua)
+        the_att.set_quality(PyTango.AttrQuality.ATTR_CHANGING)
+        the_att.set_quality(PyTango.AttrQuality.ATTR_VALID)
+
+#------------------------------------------------------------------
+
+    def write_Long64_attr_w(self,the_att):
+        print "In write_Long64_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Long64_spec_attr_w(self,the_att):
+        print "In write_Long64_spec_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Long64_ima_attr_w(self,the_att):
+        print "In write_Long64_ima_attr_w for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Long64_attr_rw(self,the_att):
+        print "In write_Long64_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Long64_spec_attr_rw(self,the_att):
+        print "In write_Long64_spec_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+#------------------------------------------------------------------
+
+    def write_Long64_ima_attr_rw(self,the_att):
+        print "In write_Long64_ima_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        print "Attribute value = ",data
+
+    def write_Long_spec_attr_rw(self,the_att):
+        print "In write_Long_spec_attr_rw for attribute ",the_att.get_name()
+        data=[]
+        the_att.get_write_value(data)
+        self.Long_spec_attr_rw = data
+        print "Attribute value = ",data
+
+
+#------------------------------------------------------------------
+
+    def write_Encoded_attr(self,the_att):
+        print('In write_Encoded_attr_rw for attribute ' + the_att.get_name())
+        self.enc_attr = the_att.get_write_value()
+        print('\tReceived string = ' + self.enc_attr[0])
+        print('\tReceived data nb = ' + str(len(self.enc_attr[1])))
+        i = 0
+        for c in self.enc_attr[1]:
+            print('\t\tdata[' + str(i) + '] = ' + c)
+            i += 1
+
+#------------------------------------------------------------------
+
+    def write_ULong_attr_rw(self,the_att):
+        print('In write_ULong_attr_rw for attribute ' + the_att.get_name())
+        self.attr_ulong_rw = the_att.get_write_value()
+        if self.attr_ulong_rw > 1000:
+            the_att.set_write_value(1111)
+
+#------------------------------------------------------------------
+
+    def write_ULong64_attr_rw(self,the_att):
+        print('In write_ULong64_attr_rw for attribute ' + the_att.get_name())
+        self.attr_ulong64_rw = the_att.get_write_value()
+
+#------------------------------------------------------------------
+
+    def write_Poll_buffRW(self,the_att):
+        print('In write_Poll_buffRW for attribute ' + the_att.get_name())
+
+#------------------------------------------------------------------
+
+    def write_State_attr_rw(self,the_att):
+        print('In write_State_attr_rw for attribute ' + the_att.get_name())
+        self.attr_state_rw = the_att.get_write_value()
+
+#------------------------------------------------------------------
+
+    def write_ULong_spec_attr_rw(self,the_att):
+        print('In write_ULong_spec_attr_rw for attribute ' + the_att.get_name())
+        nb_data = the_att.get_write_value_length()
+        ulg = the_att.get_write_value()
+        print('Received ' + str(nb_data) + ' for attribute ' + the_att.get_name());
+
+#------------------------------------------------------------------
+
+    def write_ULong64_spec_attr_rw(self,the_att):
+        print('In write_ULong64_spec_attr_rw for attribute ' + the_att.get_name())
+        nb_data = the_att.get_write_value_length()
+        ulg64 = the_att.get_write_value()
+        print('Received ' + str(nb_data) + ' for attribute ' + the_att.get_name());
+
+#------------------------------------------------------------------
+
+    def write_State_spec_attr_rw(self,the_att):
+        print('In write_State_spec_attr_rw for attribute ' + the_att.get_name())
+        nb_data = the_att.get_write_value_length()
+        sta = the_att.get_write_value()
+        print('Received ' + str(nb_data) + ' for attribute ' + the_att.get_name());
+
+#------------------------------------------------------------------
+
+    def write_DefAttr(self,the_att):
+        print('In write_DefAttr for attribute ' + the_att.get_name())
+
+#------------------------------------------------------------------
+
+    def write_DefUserAttr(self,the_att):
+        print('In write_DefUserAttr for attribute ' + the_att.get_name())
+
+#------------------------------------------------------------------
+
+    def write_DefClassAttr(self,the_att):
+        print('In write_DefClassAttr for attribute ' + the_att.get_name())
+
+#------------------------------------------------------------------
+
+    def write_DefClassUserAttr(self,the_att):
+        print('In write_DefClassUserAttr for attribute ' + the_att.get_name())
+
+#------------------------------------------------------------------
+#------------------------------------------------------------------
+#
+#                FOR ATTRIBUTES ADDED ON THE FLY
+#
+#------------------------------------------------------------------
+#------------------------------------------------------------------
+
+    def read_Added_short_attr(self,the_att):
+        print "[DevTest::read_attr] attribute name Added_short_attr"
+        the_att.set_value(5)
+
+
+
+
+
+
+
+class DevTestClass(PyTango.DeviceClass):
+    def __init__(self,name):
+        PyTango.DeviceClass.__init__(self,name)
+        self.set_type("TestDevice")
+        print 'In DevTestClass __init__'
+
+        self.add_wiz_dev_prop('aaaa','bbbb','cccc')
+        self.add_wiz_class_prop('aa','bb')
+
+
+    def signal_handler(self,in_sig):
+        print "[Class signal handler] received signal number",in_sig," for class",self.get_name()
+
+    cmd_list = {'IOVoid':[[PyTango.ArgType.DevVoid],[PyTango.ArgType.DevVoid]],
+                'IOBool':[[PyTango.ArgType.DevBoolean,"Number"],[PyTango.ArgType.DevBoolean,"Not number"]],
+                'IOShort':[[PyTango.ArgType.DevShort,"Number"],[PyTango.ArgType.DevShort,"Number * 2"]],
+                'IOLong':[[PyTango.ArgType.DevLong,"Number"],[PyTango.ArgType.DevLong,"Number * 2"]],
+                'IOFloat':[[PyTango.ArgType.DevFloat,"Number"],[PyTango.ArgType.DevFloat,"Number * 2"]],
+                'IODouble':[[PyTango.ArgType.DevDouble,"Number"],[PyTango.ArgType.DevDouble,"Number * 2"]],
+                'IOUShort':[[PyTango.ArgType.DevUShort,"Number"],[PyTango.ArgType.DevUShort,"Number * 2"]],
+                'IOULong':[[PyTango.ArgType.DevULong,"Number"],[PyTango.ArgType.DevULong,"Number * 2"]],
+                'IOString':[[PyTango.ArgType.DevString,"Word"],[PyTango.ArgType.DevString,"the palindrome is"]],
+                'IOLong64':[[PyTango.ArgType.DevLong64,"Number"],[PyTango.ArgType.DevLong64,"Number * 2"]],
+                'IOULong64':[[PyTango.ArgType.DevULong64,"Number"],[PyTango.ArgType.DevULong64,"Number * 2"]],
+                'IOCharArray':[[PyTango.ArgType.DevVarCharArray,"Array of char"],[PyTango.ArgType.DevVarCharArray,"This reversed array"]],
+                'IOShortArray':[[PyTango.ArgType.DevVarShortArray,"Array of short"],[PyTango.ArgType.DevVarShortArray,"This array * 2"]],
+                'IOLongArray':[[PyTango.ArgType.DevVarLongArray,"Array of long"],[PyTango.ArgType.DevVarLongArray,"This array * 2"]],
+                'IOFloatArray':[[PyTango.ArgType.DevVarFloatArray,"Array of float"],[PyTango.ArgType.DevVarFloatArray,"This array * 2"]],
+                'IODoubleArray':[[PyTango.ArgType.DevVarDoubleArray,"Array of double"],[PyTango.ArgType.DevVarDoubleArray,"This array * 2"]],
+                'IOUShortArray':[[PyTango.ArgType.DevVarUShortArray,"Array of unsigned short"],[PyTango.ArgType.DevVarUShortArray,"This array * 2"]],
+                'IOULongArray':[[PyTango.ArgType.DevVarULongArray,"Array of unsigned long"],[PyTango.ArgType.DevVarULongArray,"This array * 2"]],
+                'IOStringArray':[[PyTango.ArgType.DevVarStringArray,"Array of string"],[PyTango.ArgType.DevVarStringArray,"This reversed array"]],
+                'IOLongString':[[PyTango.ArgType.DevVarLongStringArray,"Array of long and string"],[PyTango.ArgType.DevVarLongStringArray,"This array of long * 2"]],
+                'IODoubleString':[[PyTango.ArgType.DevVarDoubleStringArray,"Array of double and string"],[PyTango.ArgType.DevVarDoubleStringArray,"This array of double * 2"]],
+                'IOLong64Array':[[PyTango.ArgType.DevVarLong64Array,"Array of long64"],[PyTango.ArgType.DevVarLong64Array,"This array * 2"]],
+                'IOLong64Array':[[PyTango.ArgType.DevVarULong64Array,"Array of unsigned long 64"],[PyTango.ArgType.DevVarULong64Array,"This array * 2"]],
+                'IOState':[[PyTango.ArgType.DevState,"New device state"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOThrow':[[PyTango.ArgType.DevVarLongStringArray,"Error facility"],[PyTango.ArgType.DevVoid,"An exception"]],
+                'IOReThrow':[[PyTango.ArgType.DevVarLongStringArray,"Error facility"],[PyTango.ArgType.DevVoid,"An exception"]],
+                'IODevByName':[[PyTango.ArgType.DevString,"device name"],[PyTango.ArgType.DevString,"device name (returned by name()"]],
+                'IODServDevice':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevString,"dserver device name"]],
+                'IODevListByClass':[[PyTango.ArgType.DevString,"class name"],[PyTango.ArgType.DevString,"class first device name"]],
+                'IOInitWAttr':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOAddAttribute':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOSetAttr':[[PyTango.ArgType.DevLong,"New attr value"],[PyTango.ArgType.DevVoid,"void"]],
+                'IORegSig':[[PyTango.ArgType.DevLong,"Signal number"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOUnregSig':[[PyTango.ArgType.DevLong,"Signal number"],[PyTango.ArgType.DevVoid,"void"]],
+                'IORegClassSig':[[PyTango.ArgType.DevLong,"Signal number"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOUnregClassSig':[[PyTango.ArgType.DevLong,"Signal number"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOStr1':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevString,"Just a string dynamically allocated"]],
+                'IOStr2':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevString,"A constant string"]],
+                'IOExcept':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"An exception"]],
+                'IOStartPoll':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevLong,"Constant number set to 11"]],
+                'IOPollStr1':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevString,"Just a string changing at each call"]],
+                'IOPollArray2':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVarShortArray,"An array changing at each call"]],
+                'IOArray1':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVarLongArray,"An array allocated"]],
+                'IOTrigPoll':[[PyTango.ArgType.DevString,"Command's name to trig polling"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOAttrTrigPoll':[[PyTango.ArgType.DevString,"Attribute's name to trig polling"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOShortSleep':[[PyTango.ArgType.DevVarShortArray,"Input short and sleeping time in sec"],[PyTango.ArgType.DevShort,"Output short (in * 2)"]],
+                'IOSleepExcept':[[PyTango.ArgType.DevShort,"Sleep time (sec)"],[PyTango.ArgType.DevVoid,"An exception"]],
+                'IOAttrThrowEx':[[PyTango.ArgType.DevVarShortArray,"2 elts : Attr code and throw except flag"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOAddOneElt':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'IORemoveOneElt':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOIncValue':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'IODecValue':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOChangeQuality':[[PyTango.ArgType.DevShort,"0->VALID, 1->INVALID, 2->ALARM, 3->CHANGING"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOPushEvent':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOSleep':[[PyTango.ArgType.DevUShort,"sleeping time"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOArray2':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVarShortArray,"An array without copying"]],
+                'IOStrArray':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVarStringArray,"A string array"]],
+                'IOStruct':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVarLongStringArray,"A structure type"]],
+                'IORemoveAttribute':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOSeqVecChar':[[PyTango.ArgType.DevVarCharArray,"Input char array"],[PyTango.ArgType.DevVarCharArray,"Output char array"]],
+                'IOSeqVecShort':[[PyTango.ArgType.DevVarShortArray,"Input short array"],[PyTango.ArgType.DevVarShortArray,"Output short array"]],
+                'IOSeqVecLong':[[PyTango.ArgType.DevVarLongArray,"Input long array"],[PyTango.ArgType.DevVarLongArray,"Output long array"]],
+                'IOSeqVecFloat':[[PyTango.ArgType.DevVarFloatArray,"Input float array"],[PyTango.ArgType.DevVarFloatArray,"Output float array"]],
+                'IOSeqVecDouble':[[PyTango.ArgType.DevVarDoubleArray,"Input double array"],[PyTango.ArgType.DevVarDoubleArray,"Output double array"]],
+                'IOSeqVecUShort':[[PyTango.ArgType.DevVarUShortArray,"Input unsigned short array"],[PyTango.ArgType.DevVarUShortArray,"Output unsigned short array"]],
+                'IOSeqVecULong':[[PyTango.ArgType.DevVarULongArray,"Input unsigned long array"],[PyTango.ArgType.DevVarULongArray,"Output unsigned long array"]],
+                'IOSeqVecString':[[PyTango.ArgType.DevVarStringArray,"Input string array"],[PyTango.ArgType.DevVarStringArray,"Output string array"]],
+                'IOExit':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOPushDevEncodedEvent':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOSubscribeEvent':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOUnSubscribeEvent':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'IOGetCbExecuted':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevLong,"Number of times the CB has been executed"]],
+                'OLong':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevLong,"A long"]],
+                'OULong':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevULong,"An unsigned long"]],
+                'OLongArray':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVarLongArray,"A long array"]],
+                'OULongArray':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVarULongArray,"A unsigned long array"]],
+                'OLongString':[[PyTango.ArgType.DevVoid,"void"],[PyTango.CmdArgType.DevVarLongStringArray,"A unsigned long and string array"]],
+                'GetLongSize':[[PyTango.ArgType.DevVoid,"void"],[PyTango.CmdArgType.DevShort,"Sizeof long (32 or 64 bits)"]],
+                'IOSetWAttrLimit':[[PyTango.ArgType.DevVarDoubleArray,"arr[0]==0 -> min_value, arr[0]==1 -> max_value, arr[1]=limit"],[PyTango.CmdArgType.DevVoid,"void"]],
+                'ChangeEncodedFormat':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'ChangeEncodedData':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]],
+                'PushDataReady':[[PyTango.ArgType.DevVarLongStringArray,"s[0] = attribute name, l[0] = user counter"],[PyTango.ArgType.DevVoid,"void"]],
+                'SubDeviceTst':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevBoolean,"true = sub device connected"]],
+                'IOEncoded':[[PyTango.ArgType.DevEncoded,"DevEncoded structure"],[PyTango.ArgType.DevEncoded,"DevEncoded structure"]],
+                'OEncoded':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevEncoded,"DevEncoded structure to test polling/history"]],
+                'SetGetAlarms':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVarStringArray,"DevVarStringArray containing alarm values"]],
+                'SetGetRanges':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVarStringArray,"DevVarStringArray containing ranges values"]],
+                'IOPollingInDevice':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVarStringArray,"Polling in device test outputs"]]
+               }
+
+#                'IOChangeStatus':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevVoid,"void"]]
+#                'String_attr':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ],
+#                                 {'Polling period':250}],
+#                'IOStartPoll':[[PyTango.ArgType.DevVoid,"void"],[PyTango.ArgType.DevLong,"Constant number set to 11"],
+#                               {'Polling period':400}],
+
+    attr_list = {'Short_attr':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'Long_attr':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ],
+                              {'min alarm':1000,'max alarm':1500}],
+                 'Double_attr':[[PyTango.ArgType.DevDouble,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'String_attr':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'Short_spec_attr':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,4]],
+                 'Long_spec_attr':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,10]],
+                 'Double_spec_attr':[[PyTango.ArgType.DevDouble,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,3]],
+                 'String_spec_attr':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,2]],
+                 'Short_ima_attr':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.READ,4,4]],
+                 'Long_ima_attr':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.READ,10,2]],
+                 'Double_ima_attr':[[PyTango.ArgType.DevDouble,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.READ,3,3]],
+                 'String_ima_attr':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.READ,1,2]],
+                 'attr_dq_sh':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'attr_dq_lo':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'attr_dq_db':[[PyTango.ArgType.DevDouble,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'attr_dq_str':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'attr_no_data':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'attr_wrong_type':[[PyTango.ArgType.DevDouble,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'attr_wrong_size':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,10]],
+                 'attr_no_alarm':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'Long_attr_w':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE],
+                                {'label':"Test label",'description':"Test description",'unit':"Kilogramme",'standard unit':100,
+                                 'display unit':"Et ta soeur",'format':"Tres long",'min value':0,'max value':100000,
+                                 'min alarm':1,'max alarm':99999,'min warning':2,'max warning':99998,'delta val':10000,
+                                 'delta t':1,'event abs change':30000,'event rel change':20000,'event period':2000,
+                                 'archive event abs change':33333,'archive event rel change':22222,'archive event period':3000}],
+
+                 'Float_attr_w':[[PyTango.ArgType.DevFloat,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE]],
+                 'UShort_attr_w':[[PyTango.ArgType.DevUShort,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE]],
+                 'UChar_attr_w':[[PyTango.ArgType.DevUChar,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE]],
+                 'Long_attr_with_w':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE]],
+                 'Long_attr_with_w2':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE]],
+                 'Short_attr_rw':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE]],
+                 'Short_attr_w2':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE]],
+                 'Double_attr_w':[[PyTango.ArgType.DevDouble,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE]],
+                 'String_attr_w2':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE]],
+                 'Short_attr_w':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE],
+                                 {'memorized':'true'}],
+                 'String_attr_w':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE],
+                                  {'memorized':'true'}],
+                 'Boolean_attr_w':[[PyTango.ArgType.DevBoolean,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE],
+                                  {'memorized':'True'}],
+                 'Float_attr':[[PyTango.ArgType.DevFloat,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'Boolean_attr':[[PyTango.ArgType.DevBoolean,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'UShort_attr':[[PyTango.ArgType.DevUShort,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'UChar_attr':[[PyTango.ArgType.DevUChar,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'Float_spec_attr':[[PyTango.ArgType.DevFloat,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,3]],
+                 'Boolean_spec_attr':[[PyTango.ArgType.DevBoolean,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,5]],
+                 'UShort_spec_attr':[[PyTango.ArgType.DevUShort,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,2]],
+                 'UChar_spec_attr':[[PyTango.ArgType.DevUChar,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,6]],
+                 'PollLong_attr':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'PollString_spec_attr':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,2]],
+                 'Short_spec_attr_w':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.WRITE,4],
+                                      {'max value':100}],
+                 'Short_ima_attr_w':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.WRITE,4,4]],
+                 'Long_spec_attr_w':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.WRITE,2]],
+                 'Double_spec_attr_w':[[PyTango.ArgType.DevDouble,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.WRITE,2]],
+                 'String_spec_attr_w':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.WRITE,2]],
+                 'Float_spec_attr_w':[[PyTango.ArgType.DevFloat,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.WRITE,4]],
+                 'Boolean_spec_attr_w':[[PyTango.ArgType.DevBoolean,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.WRITE,4]],
+                 'UShort_spec_attr_w':[[PyTango.ArgType.DevUShort,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.WRITE,4]],
+                 'UChar_spec_attr_w':[[PyTango.ArgType.DevUChar,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.WRITE,4]],
+                 'String_ima_attr_w':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.WRITE,2,2]],
+                 'Float_ima_attr_w':[[PyTango.ArgType.DevFloat,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.WRITE,8,8]],
+                 'UShort_ima_attr_w':[[PyTango.ArgType.DevUShort,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.WRITE,8,2]],
+                 'Short_spec_attr_rw':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ_WRITE,4]],
+                 'Long_spec_attr_rw':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ_WRITE,4]],
+                 'String_spec_attr_rw':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ_WRITE,2]],
+                 'Float_spec_attr_rw':[[PyTango.ArgType.DevFloat,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ_WRITE,4]],
+                 'UChar_spec_attr_rw':[[PyTango.ArgType.DevUChar,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ_WRITE,4]],
+                 'Short_ima_attr_rw':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.READ_WRITE,4,4]],
+                 'String_ima_attr_rw':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.READ_WRITE,2,2]],
+                 'Boolean_ima_attr_rw':[[PyTango.ArgType.DevBoolean,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.READ_WRITE,4,4]],
+                 'UShort_ima_attr_rw':[[PyTango.ArgType.DevUShort,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.READ_WRITE,2,4]],
+                 'Poll_buff':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.READ,2,2]],
+                 'Poll_buffRW':[[PyTango.ArgType.DevString,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.READ_WRITE,2,2]],
+                 'attr_asyn':[[PyTango.ArgType.DevDouble,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'attr_asyn_to':[[PyTango.ArgType.DevDouble,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'attr_asyn_except':[[PyTango.ArgType.DevDouble,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'attr_asyn_write':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE]],
+                 'attr_asyn_write_to':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE]],
+                 'attr_asyn_write_except':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE]],
+                 'event_change_tst':[[PyTango.ArgType.DevLong,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,10]],
+                 'event64_change_tst':[[PyTango.ArgType.DevLong64,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,6]],
+                 'event_quality_tst':[[PyTango.ArgType.DevDouble,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,2]],
+                 'slow_actuator':[[PyTango.ArgType.DevShort,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE]],
+                 'fast_actuator':[[PyTango.ArgType.DevDouble,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE]],
+                 'Long64_attr':[[PyTango.ArgType.DevLong64,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'Long64_spec_attr':[[PyTango.ArgType.DevLong64,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ,10]],
+                 'Long64_ima_attr':[[PyTango.ArgType.DevLong64,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.READ,10,2]],
+                 'Long64_attr_w':[[PyTango.ArgType.DevLong64,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.WRITE]],
+                 'Long64_spec_attr_w':[[PyTango.ArgType.DevLong64,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.WRITE,4]],
+                 'Long64_ima_attr_w':[[PyTango.ArgType.DevLong64,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.WRITE,4,4]],
+                 'Long64_attr_rw':[[PyTango.ArgType.DevLong64,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE]],
+                 'Long64_spec_attr_rw':[[PyTango.ArgType.DevLong64,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ_WRITE,4]],
+                 'Long64_ima_attr_rw':[[PyTango.ArgType.DevLong64,PyTango.AttrDataFormat.IMAGE,PyTango.AttrWriteType.READ_WRITE,4,4]],
+                 'Encoded_attr':[[PyTango.CmdArgType.DevEncoded,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE]],
+                 'ULong_attr':[[PyTango.CmdArgType.DevULong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'ULong64_attr':[[PyTango.CmdArgType.DevULong64,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'ULong_attr_rw':[[PyTango.CmdArgType.DevULong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE]],
+                 'ULong64_attr_rw':[[PyTango.CmdArgType.DevULong64,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE]],
+                 'State_attr_rw':[[PyTango.CmdArgType.DevState,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE]],
+                 'ULong_spec_attr_rw':[[PyTango.CmdArgType.DevULong,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ_WRITE,3]],
+                 'ULong64_spec_attr_rw':[[PyTango.CmdArgType.DevULong64,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ_WRITE,3]],
+                 'State_spec_attr_rw':[[PyTango.CmdArgType.DevState,PyTango.AttrDataFormat.SPECTRUM,PyTango.AttrWriteType.READ_WRITE,3]],
+                 'Sub_device_tst':[[PyTango.CmdArgType.DevBoolean,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'SlowAttr':[[PyTango.CmdArgType.DevDouble,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'Encoded_image':[[PyTango.CmdArgType.DevEncoded,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ]],
+                 'DefAttr':[[PyTango.CmdArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE]],
+                 'DefUserAttr':[[PyTango.CmdArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE],
+                                {'description':"User desc",'min value':30,'delta val':77, 'delta t':88,'event rel change':55,'event period':1500}],
+                 'DefClassAttr':[[PyTango.CmdArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE]],
+                 'DefClassUserAttr':[[PyTango.CmdArgType.DevLong,PyTango.AttrDataFormat.SCALAR,PyTango.AttrWriteType.READ_WRITE],
+                                {'description':"User desc",'min value':30,'delta val':77, 'delta t':88,'event rel change':55,'event period':1500}]
+              }
+
+
+if __name__ == '__main__':
+    try:
+        py = PyTango.Util(sys.argv)
+        py.add_TgClass(DevTestClass,DevTest,'DevTest')
+
+        U = PyTango.Util.instance()
+        U.server_init()
+        U.server_run()
+
+    except PyTango.DevFailed,e:
+        print '-------> Received a DevFailed exception:',e
+    except Exception,e:
+        print '-------> An unforeseen exception occured....',e
diff --git a/tests/TangoRunner.py b/tests/TangoRunner.py
new file mode 100644
index 0000000..e140ead
--- /dev/null
+++ b/tests/TangoRunner.py
@@ -0,0 +1,330 @@
+"""Running tests"""
+
+import sys
+import time
+
+from unittest import result
+from unittest.signals import registerResult
+
+from unittest import TestCase, TestSuite, suite, util
+from copy import deepcopy
+
+__unittest = True
+
+# loop parameters
+_loop = 1
+_loopSuite = 1
+_loopSuffix = '__loop'
+
+
+def _printDict(obj):
+    for key, value in sorted(obj.__dict__.items()):
+        print("\t" + str(key) + " : " + str(value))
+        
+def _hasFailed(result):
+    '''Checks if any failure occured'''
+    if result.__class__.__name__ == 'TangoTestResult' and (len(result.errors) != 0 or len(result.failures) != 0):
+        return True
+    return False
+
+class TangoTestSuite(TestSuite):
+    '''Tango-tailored Test Suite class'''
+    def __init__(self):
+        super(TangoTestSuite, self).__init__()
+        
+    def __call__(self, *args, **kwds):
+        if len(args) > 0:
+            result = args[0]
+            if not _hasFailed(result):
+                # loop count down
+                self.loop = getattr(self,'loop', _loopSuite)
+                result.loopSuite = 0
+                # flag to indicate if the test suite has finished its loop execution
+                result.loopSuiteDone = False
+                # determine if the suite consists of test cases for the same class
+                suiteClass = next(iter(self), None).__class__
+                className = suiteClass.__name__
+                if suiteClass != None.__class__ and all(isinstance(test, TangoTestCase) and test.__class__ == suiteClass for test in self):
+                    # print test suite name (only once), truncate the '__loop' suffix and show number of iterations
+                    if self.loop == _loopSuite:
+                        suiteName = className
+                        if suiteName.endswith(_loopSuffix):
+                            suiteName = suiteName[:-len(_loopSuffix)]
+                            if _loopSuite > 1:
+                                suiteName += ' [' + str(_loopSuite) + ' iter]'
+                        result.stream.writeln("\n" + suiteName + "\n")
+                    # execute test suites with suffix '__loop' multiple times
+                    if className.endswith(_loopSuffix) and self.loop > 1:
+                        # treat test methods executed in a loop as one test run
+                        testsRun = result.testsRun
+                        self.loop -= 1
+                        # TODO: check efficiency
+                        suite = deepcopy(self)
+                        suite(*args, **kwds)
+                        result.testsRun = testsRun
+                if not _hasFailed(result):
+                    result.loopSuite += 1
+                    # at the last iteration of the suite loop set the flag to True
+                    if not className.endswith(_loopSuffix) or _loopSuite <= 1 or result.loopSuite == _loopSuite:
+                        result.loopSuiteDone = True
+                    return super(TangoTestSuite, self).run(*args, **kwds)
+
+class TangoTestCase(TestCase):
+    '''Tango-tailored Test Case class'''
+    def __init__(self):
+        super(TangoTestCase, self).__init__()
+        
+    def __call__(self, *args, **kwds):
+        if len(args) > 0:
+            result = args[0]
+            if not _hasFailed(result):
+                # loop count down
+                self.loop = getattr(self,'loop', _loop)
+                result.loop = 0
+                # print test case name (only once), truncate the '__loop' suffix and show number of iterations
+                if self.loop == _loop and result.loopSuiteDone:
+                    caseName = self._testMethodName
+                    if caseName.startswith('test_'):
+                        caseName = caseName[len('test_'):]
+                    if caseName.endswith(_loopSuffix):
+                        caseName = caseName[:-len(_loopSuffix)]
+                        if _loop > 1:
+                            caseName += ' [' + str(_loop) + ' iter]'
+                    caseName = '\t' + caseName
+                    result.stream.write(caseName)
+                # run test methods with suffix '__loop' multiple times
+                if self._testMethodName.endswith(_loopSuffix) and self.loop > 1:
+                    # treat test methods executed in a loop as one test run
+                    testsRun = result.testsRun
+                    self.loop -= 1
+                    self(*args, **kwds)
+                    result.testsRun = testsRun
+                
+                if not _hasFailed(result):
+                    result.loop += 1
+                    returnResult = super(TangoTestCase, self).run(*args, **kwds)
+                    # print OK information only after the last successful execution of the test case loop and as well as test suite loop
+                    if not _hasFailed(result) and getattr(result, 'loopSuiteDone', False) and (not self._testMethodName.endswith(_loopSuffix)  or _loop <= 1 or result.loop == _loop):
+                        result.stream.writeln(" --> OK")
+                    return returnResult
+
+
+class _WritelnDecorator(object):
+    """Used to decorate file-like objects with a handy 'writeln' method"""
+    def __init__(self,stream):
+        self.stream = stream
+
+    def __getattr__(self, attr):
+        if attr in ('stream', '__getstate__'):
+            raise AttributeError(attr)
+        return getattr(self.stream,attr)
+
+    def writeln(self, arg=None):
+        if arg:
+            self.write(arg)
+        self.write('\n') # text-mode streams translate to \r\n if needed
+
+
+class TangoTestResult(result.TestResult):
+    """A test result class that can print formatted text results to a stream.
+
+    Used by TangoTestRunner.
+    """
+    separator1 = '=' * 70
+    separator2 = '-' * 70
+
+    def __init__(self, stream, descriptions, verbosity):
+        super(TangoTestResult, self).__init__()
+        self.stream = stream
+        self.showAll = verbosity > 2
+        self.dots = verbosity == 2
+        self.tangoPrint = verbosity == 1
+        self.descriptions = descriptions
+
+    def getDescription(self, test):
+        testString = str(test).split(' ')
+        if len(testString) is 2:
+            testName = testString[0]
+            testClass = testString[1][1:-1]
+            if self.loop > 1:
+                loop = ' [' + str(self.loop) + ' iter]'
+            else:
+                loop = ''
+            if self.loopSuite > 1:
+                loopSuite = ' [' + str(self.loopSuite) + ' iter]'
+            else:
+                loopSuite = ''
+            return str(testClass + loopSuite + ' :: ' + testName + loop)
+        else:
+            return str(test)
+        
+        doc_first_line = test.shortDescription()
+        if self.descriptions and doc_first_line:
+            return '\n'.join((str(test), doc_first_line))
+        else:
+            return str(test)
+
+    def startTest(self, test):
+        super(TangoTestResult, self).startTest(test)
+        if self.showAll:
+            self.stream.write(self.getDescription(test))
+            self.stream.write(" ... ")
+            self.stream.flush()
+
+    def addSuccess(self, test):
+        super(TangoTestResult, self).addSuccess(test)
+        if self.showAll:
+            self.stream.writeln("ok")
+        elif self.dots:
+            self.stream.write('.')
+            self.stream.flush()
+
+    def addError(self, test, err):
+        super(TangoTestResult, self).addError(test, err)
+        if self.showAll:
+            self.stream.writeln("ERROR")
+        elif self.dots:
+            self.stream.write('E')
+            self.stream.flush()
+
+    def addFailure(self, test, err):
+        super(TangoTestResult, self).addFailure(test, err)
+        if self.showAll:
+            self.stream.writeln("FAIL")
+        elif self.dots:
+            self.stream.write('F')
+            self.stream.flush()
+
+    def addSkip(self, test, reason):
+        super(TangoTestResult, self).addSkip(test, reason)
+        if self.showAll:
+            self.stream.writeln("skipped {0!r}".format(reason))
+        elif self.dots:
+            self.stream.write("s")
+            self.stream.flush()
+
+    def addExpectedFailure(self, test, err):
+        super(TangoTestResult, self).addExpectedFailure(test, err)
+        if self.showAll:
+            self.stream.writeln("expected failure")
+        elif self.dots:
+            self.stream.write("x")
+            self.stream.flush()
+
+    def addUnexpectedSuccess(self, test):
+        super(TangoTestResult, self).addUnexpectedSuccess(test)
+        if self.showAll:
+            self.stream.writeln("unexpected success")
+        elif self.dots:
+            self.stream.write("u")
+            self.stream.flush()
+
+    def printErrors(self):
+        if self.dots or self.showAll:
+            self.stream.writeln()
+        self.printErrorList('ERROR', self.errors)
+        self.printErrorList('FAIL', self.failures)
+
+    def printErrorList(self, flavour, errors):
+        for test, err in errors:
+            self.stream.writeln(self.separator1)
+            self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
+            self.stream.writeln(self.separator2)
+            self.stream.writeln("%s" % err)
+
+
+class TangoTestRunner(object):
+    """A test runner class that displays results in textual form.
+
+    It prints out the names of tests as they are run, errors as they
+    occur, and a summary of the results at the end of the test run.
+    """
+    resultclass = TangoTestResult
+
+    def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1,
+                 failfast=False, buffer=False, resultclass=None, loopSuite=1, loop=1):
+        self.stream = _WritelnDecorator(stream)
+        self.descriptions = descriptions
+        self.verbosity = verbosity
+        self.failfast = failfast
+        self.buffer = buffer
+        # set loop parameters
+        global _loopSuite, _loop
+        _loopSuite = loopSuite
+        _loop = loop
+        if resultclass is not None:
+            self.resultclass = resultclass
+
+    def _makeResult(self):
+        return self.resultclass(self.stream, self.descriptions, self.verbosity)
+
+    def run(self, test):
+        "Run the given test case or test suite."
+
+        # convert test classes to Tango Test Suite compliant
+        def convertToTango(test):
+            try:
+                iter(test)
+            except TypeError:
+                test.__class__.__bases__ = (TangoTestCase, )
+            else:
+                test.__class__ = TangoTestSuite
+                for t in test:
+                    convertToTango(t)
+        convertToTango(test)
+        
+        result = self._makeResult()
+        registerResult(result)
+        result.failfast = self.failfast
+        result.buffer = self.buffer
+        startTime = time.time()
+        startTestRun = getattr(result, 'startTestRun', None)
+        if startTestRun is not None:
+            startTestRun()
+        try:
+            test(result)
+        finally:
+            stopTestRun = getattr(result, 'stopTestRun', None)
+            if stopTestRun is not None:
+                stopTestRun()
+        stopTime = time.time()
+        timeTaken = stopTime - startTime
+        result.printErrors()
+        if hasattr(result, 'separator2'):
+            self.stream.writeln(result.separator2)
+        run = result.testsRun
+        self.stream.writeln("Ran %d test%s in %.3fs" %
+                            (run, run != 1 and "s" or "", timeTaken))
+        self.stream.writeln()
+
+        expectedFails = unexpectedSuccesses = skipped = 0
+        try:
+            results = map(len, (result.expectedFailures,
+                                result.unexpectedSuccesses,
+                                result.skipped))
+        except AttributeError:
+            pass
+        else:
+            expectedFails, unexpectedSuccesses, skipped = results
+
+        infos = []
+        if not result.wasSuccessful():
+            self.stream.write("FAILED")
+            failed, errored = map(len, (result.failures, result.errors))
+            if failed:
+                infos.append("failures=%d" % failed)
+            if errored:
+                infos.append("errors=%d" % errored)
+        else:
+            self.stream.write("OK")
+        if skipped:
+            infos.append("skipped=%d" % skipped)
+        if expectedFails:
+            infos.append("expected failures=%d" % expectedFails)
+        if unexpectedSuccesses:
+            infos.append("unexpected successes=%d" % unexpectedSuccesses)
+        if infos:
+            self.stream.writeln(" (%s)" % (", ".join(infos),))
+        else:
+            self.stream.write("\n")
+        return result

-- 
Packaging for pytango



More information about the debian-science-commits mailing list