diff --git a/ExperimentDetails-srv.py b/ExperimentDetails-srv.py
index 3aac624d036973706ec453df4306c53d4dae06f3..0456016de10e55471851deb8f138792537561aa0 100755
--- a/ExperimentDetails-srv.py
+++ b/ExperimentDetails-srv.py
@@ -5,7 +5,7 @@
 #
 # file :        Experiment_Details.py
 #
-# description : Python source for the Experiment_Details and its commands. 
+# description : Python source for the Experiment_Details and its commands.
 #                The class is derived from Device. It represents the
 #                CORBA servant object which will be accessed from the
 #                network. All commands which can be executed on the
@@ -64,7 +64,7 @@ class Experiment_Details(PyTango.Device_4Impl):
 #	Device destructor
 #------------------------------------------------------------------
 	def delete_device(self):
-		print "[Device delete_device method] for device",self.get_name()
+		print ("[Device delete_device method] for device",self.get_name())
 
 
 #------------------------------------------------------------------
@@ -82,6 +82,7 @@ class Experiment_Details(PyTango.Device_4Impl):
 		self.StorageMngrDev = None
 		self.ProposalList = []
 		self.InvestigationList = []
+		self.ActionLog = []
 		self.free_space_readout_time = 0
 		self.attr_FreeSpaceScratch_read = 0
 		self.attr_FreeSpaceOnline_read = 0
@@ -109,9 +110,10 @@ class Experiment_Details(PyTango.Device_4Impl):
 			self.UserId = attr_prop['__value'][0]
 		#
 		if self.Logged_in:
-			self.retrieve_proposal_investigations()
 			if len(self.ActiveInvestigation.strip()):
 				self.set_active_investigation()
+			else:
+				self.retrieve_proposal_investigations()
 
 
 #------------------------------------------------------------------
@@ -125,7 +127,7 @@ class Experiment_Details(PyTango.Device_4Impl):
 		if (time.time() - self.last_time_activity) > (2 * 86400):
 			self.Logout()
 		self.last_time_activity = time.time()
-			
+
 
 
 #==================================================================
@@ -147,9 +149,9 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def read_UserLogin(self, attr):
 		#print "In ", self.get_name(), "::read_UserLogin()"
-		
+
 		#	Add your own code here
-		
+
 		attr_User_read = self.UserLogin
 		attr.set_value(attr_User_read)
 
@@ -160,12 +162,13 @@ class Experiment_Details(PyTango.Device_4Impl):
 	def write_UserLogin(self, attr):
 		#print "In ", self.get_name(), "::write_UserLogin()"
 		self.UserLogin = attr.get_write_value()
-		#------------------------------------------------------------------
+
+#------------------------------------------------------------------
 #	Read ActiveInvestigation attribute
 #------------------------------------------------------------------
 	def read_ActiveInvestigation(self, attr):
 		#print "In ", self.get_name(), "::read_ActiveInvestigation()"
-		
+
 		#	Add your own code here
 		attr_ActiveInvestigation_read = self.ActiveInvestigation
 		attr.set_value(attr_ActiveInvestigation_read)
@@ -176,7 +179,7 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def write_ActiveInvestigation(self, attr):
 		#print "In ", self.get_name(), "::write_ActiveInvestigation()"
-		
+
 		#	Add your own code here
 		#if not self.Logged_in:
 		#  raise Exception("User not logged in!")
@@ -191,7 +194,7 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def read_Logged_in(self, attr):
 		#print "In ", self.get_name(), "::read_Logged_in()"
-		
+
 		#	Add your own code here
 		attr_Logged_in_read = self.Logged_in
 		attr.set_value(attr_Logged_in_read)
@@ -201,9 +204,9 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def read_UserId(self, attr):
 		#print "In ", self.get_name(), "::read_UserId()"
-		
+
 		#	Add your own code here
-	
+
 		attr_UserId_read = self.UserId
 		attr.set_value(attr_UserId_read)
 
@@ -213,7 +216,7 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def read_StaffMember(self, attr):
 		#print "In ", self.get_name(), "::read_StaffMember()"
-		
+
 		#	Add your own code here
 		attr_StaffMember_read = self.StaffMember
 		attr.set_value(attr_StaffMember_read)
@@ -224,7 +227,7 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def read_DataPath(self, attr):
 		#print "In ", self.get_name(), "::read_DataPath()"
-		
+
 		#	Add your own code here
 		attr_DataPath_read = self.DataPath
 		attr.set_value(attr_DataPath_read)
@@ -242,9 +245,9 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def read_ProposalList(self, attr):
 		#print "In ", self.get_name(), "::read_ProposalList()"
-		
+
 		#	Add your own code here
-		
+
 		attr_ProposalList_read = self.ProposalList
 		attr.set_value(attr_ProposalList_read)
 
@@ -253,9 +256,9 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def read_InvestigationList(self, attr):
 		#print "In ", self.get_name(), "::read_InvestigationList()"
-		
+
 		#	Add your own code here
-		
+
 		attr_InvestigationList_read = self.InvestigationList
 		attr.set_value(attr_InvestigationList_read)
 
@@ -264,7 +267,7 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def read_FreeSpaceScratch(self, attr):
 		#print "In ", self.get_name(), "::read_FreeSpaceScratch()"
-		
+
 		#	Add your own code here
 		self.update_disk_usage_info()
 		attr.set_value(self.attr_FreeSpaceScratch_read)
@@ -275,7 +278,7 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def read_FreeSpaceOnline(self, attr):
 		#print "In ", self.get_name(), "::read_FreeSpaceOnline()"
-		
+
 		#	Add your own code here
 		self.update_disk_usage_info()
 		attr.set_value(self.attr_FreeSpaceOnline_read)
@@ -285,7 +288,7 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def read_FreeSpaceScratch_TB(self, attr):
 		#print "In ", self.get_name(), "::read_FreeSpaceScratch_TB()"
-		
+
 		#	Add your own code here
 		self.update_disk_usage_info()
 		attr.set_value(self.attr_FreeSpaceScratch_TB_read)
@@ -296,11 +299,21 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def read_FreeSpaceOnline_TB(self, attr):
 		#print "In ", self.get_name(), "::read_FreeSpaceOnline_TB()"
-		
+
 		#	Add your own code here
 		self.update_disk_usage_info()
 		attr.set_value(self.attr_FreeSpaceOnline_TB_read)
 
+#------------------------------------------------------------------
+#	Read ActionLog attribute
+#------------------------------------------------------------------
+	def read_ActionLog(self, attr):
+		#print "In ", self.get_name(), "::read_ActionLog()"
+
+		#	Add your own code here
+
+		attr_ActionLog_read = self.ActionLog
+		attr.set_value(attr_ActionLog_read)
 
 #==================================================================
 #
@@ -311,24 +324,16 @@ class Experiment_Details(PyTango.Device_4Impl):
 #	Login()
 #------------------------------------------------------------------
 	def Login(self, password):
-		if self.StorageMngrDev == None:
-			self.connect_to_storage_manager()
-	      	#
 		self.StaffMember = False
-	      	#
-	      	arg_in = [self.UserLogin,password,self.TAG]
-	      	resp = self.StorageMngrDev.Authenticate(arg_in)
-	      	if resp.find("OK:") < 0:
-			self.Logged_in = False
-			raise Exception("User authentication failed!")
-	      	else:
-			only_resp = (resp.upper().split("OK:")[-1]).rstrip("\n")
-			self.UserId = only_resp.split(":")[0]
-			if only_resp.find(":ADMIN") > 0:
-				self.StaffMember = True
-	      	#
-	      	self.Logged_in = True
-	      	self.retrieve_proposal_investigations()
+		self.Logged_in = False
+		resp = self.CheckCredentials([self.UserLogin,password])
+		only_resp = (resp.upper().split("OK:")[-1]).rstrip("\n")
+		self.UserId = only_resp.split(":")[0]
+		if only_resp.find(":ADMIN") > 0:
+			self.StaffMember = True
+			self.log_action("Authenticated user is staff member")
+		self.Logged_in = True
+		self.retrieve_proposal_investigations()
 		self.memorize_status()
 
 #------------------------------------------------------------------
@@ -341,8 +346,25 @@ class Experiment_Details(PyTango.Device_4Impl):
 		self.ProposalList = []
 		self.InvestigationList = []
 		self.StaffMember = False
+		self.log_action("Authenticated user logout")
 		self.memorize_status()
 
+#------------------------------------------------------------------
+#	Login()
+#------------------------------------------------------------------
+	def CheckCredentials(self, argin):
+		if self.StorageMngrDev == None:
+			self.connect_to_storage_manager()
+		UserLogin = argin[0]
+		password = argin[1]
+		arg_in = [UserLogin,password,self.TAG]
+		self.log_action("CheckCredentials user %s" % UserLogin)
+		resp = self.StorageMngrDev.Authenticate(arg_in)
+		self.log_action("CheckCredentials reply %s" % resp.strip())
+		if resp.find("OK:") < 0:
+			raise Exception("User authentication failed!")
+		return resp.strip()
+
 
 #------------------------------------------------------------------
 #	Dump status into DB
@@ -360,7 +382,7 @@ class Experiment_Details(PyTango.Device_4Impl):
 #------------------------------------------------------------------
 	def retrieve_proposal_investigations(self):
 		if self.StorageMngrDev == None:
-	    		self.connect_to_storage_manager()
+			self.connect_to_storage_manager()
 		resp = self.StorageMngrDev.ListProposal([self.UserId, self.TAG])
 		if resp.upper().find("OK:") >= 0:
 			self.ProposalList = resp.split(":")
@@ -383,28 +405,62 @@ class Experiment_Details(PyTango.Device_4Impl):
 #	Set Active Investigation
 #------------------------------------------------------------------
 	def set_active_investigation(self):
-		
-		arg_in = [self.UserId, self.TAG, self.ActiveInvestigation, self.ActiveInvestigation]
-		
+		self.log_action("set_active_investigation %s" % self.ActiveInvestigation)
+		self.retrieve_proposal_investigations()
 		if self.ActiveInvestigation in self.InvestigationList:
-		  # Investigation already created
-		  res = 'OK'
-		elif self.ActiveInvestigation in self.ProposalList:
-		  arg_in.pop()
-		  res=self.StorageMngrDev.command_inout("CreateInvestigationFromProposal",arg_in)
-		else:
-		  res=self.StorageMngrDev.command_inout("CreateInvestigation",arg_in)
+			# Investigation already created
+			res = 'OK'
+			self.log_action("investigation already exists")
+			return
+		arg_in = [self.UserId, self.TAG, self.ActiveInvestigation, self.ActiveInvestigation]
+		proposalFound = False
+		for proposal in self.ProposalList:
+			if self.ActiveInvestigation.startswith(proposal):
+				arg_in[2] = proposal
+				proposalFound = True
+				self.log_action("found an existing proposal: %s" % proposal)
+				break
+		if not proposalFound and self.ActiveInvestigation[:8].isdigit():
+			# VUO proposals with a corresponding Investigation are not listed in
+			# self.ProposalList, let's suppose that the first part is a propsal ID
+			proposal = self.ActiveInvestigation[:8]
+			if self.StaffMember:
+				# special case of a staff memeber
+				arg_in[2] = proposal
+				proposalFound = True
+				self.log_action("staff member will try this proposal: %s" % proposal)
+			else:
+				# normal case of an external memeber
+				for Investigation in self.InvestigationList:
+					if Investigation.startswith(proposal):
+						arg_in[2] = proposal
+						self.log_action("user will try this proposal: %s" % proposal)
+						proposalFound = True
+						break
+		if proposalFound:
+			res=self.StorageMngrDev.command_inout("CreateInvestigationFromProposal",arg_in)
+			self.log_action("CreateInvestigationFromProposal() reply %s" % res)
+			if res[:2] =='OK':
+				return
+		res = self.StorageMngrDev.command_inout("CreateInvestigation",arg_in)
+		self.log_action("CreateInvestigation() reply %s" % res)
 		if res[:2]!='OK':
-		  print res
-		  self.ActiveInvestigation = ""
-		  raise Exception("Create Investigation Failed!")
+			self.ActiveInvestigation = ""
+			raise Exception("Create Investigation Failed!")
 
+#------------------------------------------------------------------
+#	Action internal log
+#------------------------------------------------------------------
+	def log_action(self, msg):
+		self.ActionLog.append(msg)
+		self.ActionLog = self.ActionLog[-100:]
 
 #------------------------------------------------------------------
 #	Storage manager connection
 #------------------------------------------------------------------
 	def connect_to_storage_manager(self):
-	  self.StorageMngrDev = PyTango.DeviceProxy(self.StorageManagerDevice)
+		self.StorageMngrDev = PyTango.DeviceProxy(self.StorageManagerDevice)
+		self.StorageMngrDev.set_timeout_millis(10000)
 
 #------------------------------------------------------------------
 #	Update disk usage info
@@ -451,6 +507,9 @@ class Experiment_DetailsClass(PyTango.DeviceClass):
 
 	#	Command definitions
 	cmd_list = {
+		'CheckCredentials':
+		    [[PyTango.DevVarStringArray,"Username,Password"],
+		    [PyTango.DevString,""]],
 		'Login':
 		    [[PyTango.DevString,"Password"],
 		    [PyTango.DevVoid,""]],
@@ -538,7 +597,11 @@ class Experiment_DetailsClass(PyTango.DeviceClass):
 				'unit':"TB",
 				'standard unit':"TB",
 				'display unit':"TB",
-			} ]
+			} ],
+		'ActionLog':
+			[[PyTango.DevString,
+			PyTango.SPECTRUM,
+			PyTango.READ,100]]
 		}
 
 
@@ -548,7 +611,6 @@ class Experiment_DetailsClass(PyTango.DeviceClass):
 	def __init__(self, name):
 		PyTango.DeviceClass.__init__(self, name)
 		self.set_type(name);
-		print "In Experiment_DetailsClass  constructor"
 
 #==================================================================
 #
@@ -564,7 +626,7 @@ if __name__ == '__main__':
 		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
+	except PyTango.DevFailed as e:
+		print ('-------> Received a DevFailed exception:',e)
+	except Exception as e:
+		print ('-------> An unforeseen exception occured....',e)