diff --git a/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudPersonSlapInterfaceWorkflow.py b/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudPersonSlapInterfaceWorkflow.py
index 0d459fd581c5360ad71f2a5e02009c4549bef424..4c7fe3008eafc1ac51843c4572dfe766bc5199e9 100644
--- a/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudPersonSlapInterfaceWorkflow.py
+++ b/master/bt5/slapos_cloud/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudPersonSlapInterfaceWorkflow.py
@@ -1253,3 +1253,208 @@ class TestSlapOSCorePersonRequestToken(SlapOSTestCaseMixin):
     self.assertEqual(
       token.getPortalType(), "One Time Restricted Access Token")
     self.assertEqual(token.getUrlMethod(), "POST")
+
+
+
+class TestSlapOSCorePersonNotify(SlapOSTestCaseMixin):
+
+  def afterSetUp(self):
+    SlapOSTestCaseMixin.afterSetUp(self)
+    self.person = self.makePerson()
+    self.tic()
+
+  def beforeTearDown(self):
+    pass
+  
+  def test_Person_notify_mandatory_argument(self):
+    self.assertRaises(TypeError, self.person.notify)
+    self.assertRaises(TypeError, self.person.notify, support_request_title="a")
+    self.assertRaises(TypeError, self.person.notify, support_request_title="a", support_request_description="b")
+
+  def test_Person_notify_unknown_aggregate(self):
+    self.assertRaises(KeyError, self.person.notify,
+     support_request_title="a", support_request_description="b", aggregate="c")
+
+  def test_Person_notify_computer_node(self):
+    compute_node, _ = self._makeComputeNode()
+    self._test_Person_notify(compute_node)
+
+  def test_Person_notify_instance_tree(self):
+    person = self.portal.person_module.template_member\
+         .Base_createCloneDocument(batch_mode=1)
+    instance_tree = self.portal\
+      .instance_tree_module.template_instance_tree\
+      .Base_createCloneDocument(batch_mode=1)
+    instance_tree.validate()
+    new_id = self.generateNewId()
+    instance_tree.edit(
+        title= "Test hosting sub ticket %s" % new_id,
+        reference="TESTHST-%s" % new_id,
+        destination_section_value=person
+    )
+    self._test_Person_notify(instance_tree)
+
+  def test_Person_notify_software_installation(self):
+    self._makeComputeNode()
+    software_installation = self.portal\
+       .software_installation_module.template_software_installation\
+       .Base_createCloneDocument(batch_mode=1)
+    software_installation.edit(
+       url_string=self.generateNewSoftwareReleaseUrl(),
+       aggregate=self.compute_node.getRelativeUrl(),
+       reference='TESTSOFTINSTS-%s' % self.generateNewId(),
+       title='Start requested for %s' % self.compute_node.getUid()
+     )
+    software_installation.validate()
+    software_installation.requestStart()
+    self._test_Person_notify(software_installation)
+
+  def _test_Person_notify(self, aggregate_value):
+
+    # Step 1: Notify
+    self.person.notify(
+      support_request_title="A",
+      support_request_description="B",
+      aggregate=aggregate_value.getRelativeUrl()
+    )
+
+    # Step 2: Check return
+    support_request_relative_url = self.person.REQUEST.get(
+       "support_request_relative_url", None) 
+    self.assertNotEqual(None, support_request_relative_url)
+    support_request_in_progress = self.person.REQUEST.get(
+      "support_request_in_progress", None) 
+    self.assertEqual(support_request_in_progress, support_request_relative_url)
+
+    support_request = self.portal.restrictedTraverse(support_request_in_progress)
+    self.assertEqual(support_request.getSimulationState(),
+                     "validated")
+    self.assertEqual(support_request.getTitle(), "A")
+    self.assertEqual(support_request.getDescription(), "B")
+    self.assertNotEqual(support_request.getStartDate(), None)
+    self.assertEqual(support_request.getDestinationDecision(),
+      self.person.getRelativeUrl())
+    self.assertEqual(support_request.getAggregateValue(),
+      aggregate_value)
+    self.assertEqual(support_request.getResource(),
+      "service_module/slapos_crm_monitoring")
+
+    # Step 3: Reset REQUEST and check in progress before catalog
+    self.person.REQUEST.set(
+       "support_request_relative_url", None)
+    support_request_relative_url = self.person.REQUEST.get(
+       "support_request_relative_url", None) 
+    self.assertEqual(None, support_request_relative_url)
+
+    self.person.notify(
+      support_request_title="A",
+      support_request_description="B",
+      aggregate=aggregate_value.getRelativeUrl()
+    )
+
+    support_request_relative_url = self.person.REQUEST.get(
+       "support_request_relative_url", None) 
+    self.assertNotEqual(None, support_request_relative_url)
+ 
+    self.assertEqual(support_request_in_progress, support_request_relative_url)
+
+    self.tic()
+
+    # Step 4: Reset parameters and check if the support request is got again.
+    self.person.REQUEST.set(
+       "support_request_relative_url", None)
+    support_request_relative_url = self.person.REQUEST.get(
+       "support_request_relative_url", None) 
+    self.assertEqual(None, support_request_relative_url)
+    support_request_in_progress = self.person.REQUEST.set(
+      "support_request_in_progress", None)
+    support_request_in_progress = self.person.REQUEST.set(
+      "support_request_in_progress", None) 
+    self.assertEqual(support_request_in_progress, None)
+
+    self.commit()
+    self.person.notify(
+      support_request_title="A",
+      support_request_description="B",
+      aggregate=aggregate_value.getRelativeUrl()
+    )
+
+    support_request_relative_url = self.person.REQUEST.get(
+       "support_request_relative_url", None) 
+    self.assertNotEqual(None, support_request_relative_url)
+    support_request_in_progress = self.person.REQUEST.get(
+      "support_request_in_progress", None) 
+    self.assertEqual(support_request_in_progress, support_request_relative_url)
+  
+    # Check if it is the same Support Request as before
+    self.assertEqual(support_request.getRelativeUrl(),
+      support_request_relative_url)
+
+    # Step 5: Retry the same thing, but now on suspended state
+    support_request.suspend()
+
+    self.tic()
+    self.person.REQUEST.set(
+       "support_request_relative_url", None)
+    support_request_relative_url = self.person.REQUEST.get(
+       "support_request_relative_url", None) 
+    self.assertEqual(None, support_request_relative_url)
+    support_request_in_progress = self.person.REQUEST.set(
+      "support_request_in_progress", None)
+    support_request_in_progress = self.person.REQUEST.set(
+      "support_request_in_progress", None) 
+    self.assertEqual(support_request_in_progress, None)
+
+    self.commit()
+    self.person.notify(
+      support_request_title="A",
+      support_request_description="B",
+      aggregate=aggregate_value.getRelativeUrl()
+    )
+
+    support_request_relative_url = self.person.REQUEST.get(
+       "support_request_relative_url", None) 
+    self.assertNotEqual(None, support_request_relative_url)
+    support_request_in_progress = self.person.REQUEST.get(
+      "support_request_in_progress", None) 
+    self.assertEqual(support_request_in_progress, support_request_relative_url)
+  
+
+    # Check if it is the same Support Request as before and still suspended
+    self.assertEqual(support_request.getRelativeUrl(),
+      support_request_relative_url)
+    self.assertEqual(support_request.getSimulationState(), "suspended")
+
+    # Step 6: If the support request is closed, create indeed a new one.
+    support_request.invalidate()
+    self.tic()
+
+    self.person.REQUEST.set("support_request_relative_url", None)
+    support_request_relative_url = self.person.REQUEST.get(
+       "support_request_relative_url", None) 
+    self.assertEqual(None, support_request_relative_url)
+    support_request_in_progress = self.person.REQUEST.set(
+      "support_request_in_progress", None)
+    support_request_in_progress = self.person.REQUEST.set(
+      "support_request_in_progress", None) 
+    self.assertEqual(support_request_in_progress, None)
+
+    self.commit()
+    self.person.notify(
+      support_request_title="A",
+      support_request_description="B",
+      aggregate=aggregate_value.getRelativeUrl()
+    )
+
+    support_request_relative_url = self.person.REQUEST.get(
+       "support_request_relative_url", None) 
+    self.assertNotEqual(None, support_request_relative_url)
+    support_request_in_progress = self.person.REQUEST.get(
+      "support_request_in_progress", None) 
+    self.assertEqual(support_request_in_progress, support_request_relative_url)
+
+    # Check if it is the another Support Request
+    self.assertEqual(support_request.getSimulationState(), "invalidated")
+
+    self.assertNotEqual(support_request.getRelativeUrl(),
+      support_request_relative_url)
diff --git a/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/script_Person_notify.py b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/script_Person_notify.py
new file mode 100644
index 0000000000000000000000000000000000000000..723a27624c146bd6f14b7963860b5b9f79ea5d04
--- /dev/null
+++ b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/script_Person_notify.py
@@ -0,0 +1,60 @@
+person = state_change['object']
+portal = person.getPortalObject()
+# Get required arguments
+kwargs = state_change.kwargs
+
+# Required args
+# Raise TypeError if all parameters are not provided
+try:
+  support_request_title = kwargs['support_request_title']
+  description = kwargs['support_request_description']
+  # Aggregate can be None, so it isn't included on the kwargs
+  aggregate = kwargs["aggregate"]
+except KeyError:
+  raise TypeError, "Person_requestSupportRequest takes exactly 3 arguments"
+
+aggregate_value = portal.restrictedTraverse(aggregate)
+
+support_request_in_progress = portal.portal_catalog.getResultValue(
+  portal_type = 'Support Request',
+  title = support_request_title,
+  simulation_state = ["validated", "submitted", "suspended"],
+  default_aggregate_uid = aggregate_value.getUid(),
+)
+
+if support_request_in_progress is not None:
+  context.REQUEST.set("support_request_relative_url",
+    support_request_in_progress.getRelativeUrl())
+  context.REQUEST.set("support_request_in_progress",
+    support_request_in_progress.getRelativeUrl())
+  return
+
+support_request_in_progress = context.REQUEST.get("support_request_in_progress", None)
+
+if support_request_in_progress is not None:
+  support_request = portal.restrictedTraverse(support_request_in_progress, None)
+  if support_request and support_request.getTitle() == support_request_title and \
+      support_request.getAggregateUid() == aggregate_value.getUid():
+    context.REQUEST.set("support_request_relative_url", support_request_in_progress)
+    return
+
+# Ensure resoure is Monitoring
+resource = portal.service_module.\
+                  slapos_crm_monitoring.getRelativeUrl()
+
+support_request = portal.restrictedTraverse(
+        portal.portal_preferences.getPreferredSupportRequestTemplate())\
+         .Base_createCloneDocument(batch_mode=1)
+
+support_request.edit(
+    title = support_request_title,
+    description = description,
+    start_date = DateTime(),
+    destination_decision=person.getRelativeUrl(),
+    aggregate_value=aggregate_value,
+    resource=resource
+  )
+support_request.validate()
+
+context.REQUEST.set("support_request_relative_url", support_request.getRelativeUrl())
+context.REQUEST.set("support_request_in_progress", support_request.getRelativeUrl())
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.xml b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/script_Person_notify.xml
similarity index 76%
rename from master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.xml
rename to master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/script_Person_notify.xml
index d619e79b71b9331b2a5888de43ab78d5fd48b318..de4b769be6d59728accc874082fc06349365440d 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.xml
+++ b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/script_Person_notify.xml
@@ -2,7 +2,7 @@
 <ZopeData>
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
-      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+      <global name="Workflow Script" module="erp5.portal_type"/>
     </pickle>
     <pickle>
       <dictionary>
@@ -50,11 +50,25 @@
         </item>
         <item>
             <key> <string>_params</string> </key>
-            <value> <string>message_title, message, destination_relative_url</string> </value>
+            <value> <string>state_change</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
         </item>
         <item>
             <key> <string>id</string> </key>
-            <value> <string>SupportRequest_trySendNotificationMessage</string> </value>
+            <value> <string>script_Person_notify</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Script</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Person_notify</string> </value>
         </item>
       </dictionary>
     </pickle>
diff --git a/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/script_Person_requestSupportRequest.py b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/script_Person_requestSupportRequest.py
new file mode 100644
index 0000000000000000000000000000000000000000..2197480ade751db517859542ba465542a96403f8
--- /dev/null
+++ b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/script_Person_requestSupportRequest.py
@@ -0,0 +1,39 @@
+person = state_change['object']
+portal = person.getPortalObject()
+# Get required arguments
+kwargs = state_change.kwargs
+
+# Required args
+# Raise TypeError if all parameters are not provided
+try:
+  support_request_title = kwargs['support_request_title']
+  resource = kwargs['support_request_resource']
+  description = kwargs['support_request_description']
+  # Aggregate can be None, so it isn't included on the kwargs
+  aggregate = kwargs.get("support_request_aggregate", None)
+except KeyError:
+  raise TypeError, "Person_requestSupportRequest takes exactly 4 arguments"
+
+tag = "%s_%s_SupportRequestInProgress" % (person.getUid(), 
+                               support_request_title)
+if (portal.portal_activities.countMessageWithTag(tag) > 0):
+  # The software instance is already under creation but can not be fetched from catalog
+  # As it is not possible to fetch informations, it is better to raise an error
+  raise NotImplementedError(tag)
+
+support_request_portal_type = "Support Request"
+
+module = portal.getDefaultModule(portal_type=support_request_portal_type)
+support_request = module.newContent(
+  portal_type=support_request_portal_type,
+  title=support_request_title,
+  description=description,
+  resource=resource,
+  destination_decision_value=person,
+  aggregate=aggregate,
+  specialise="sale_trade_condition_module/slapos_ticket_trade_condition",
+  activate_kw={'tag': tag}
+)
+context.REQUEST.set("support_request_relative_url", support_request.getRelativeUrl())
+
+support_request.approveRegistration()
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_upgradeInstanceTree.xml b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/script_Person_requestSupportRequest.xml
similarity index 76%
rename from master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_upgradeInstanceTree.xml
rename to master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/script_Person_requestSupportRequest.xml
index 609aa59614c8aa22ee66ae1dc728dc880b18b2ad..57f56ba43549480a698a72c757d8e4079575bae4 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_upgradeInstanceTree.xml
+++ b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/script_Person_requestSupportRequest.xml
@@ -2,7 +2,7 @@
 <ZopeData>
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
-      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+      <global name="Workflow Script" module="erp5.portal_type"/>
     </pickle>
     <pickle>
       <dictionary>
@@ -50,11 +50,25 @@
         </item>
         <item>
             <key> <string>_params</string> </key>
-            <value> <string></string> </value>
+            <value> <string>state_change</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
         </item>
         <item>
             <key> <string>id</string> </key>
-            <value> <string>UpgradeDecision_upgradeInstanceTree</string> </value>
+            <value> <string>script_Person_requestSupportRequest</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Script</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Person_requestSupportRequest</string> </value>
         </item>
       </dictionary>
     </pickle>
diff --git a/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/state_draft.xml b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/state_draft.xml
index 017bfd471635d235dbb8a2401f7d9a7951c93a82..5ae61cb269eb6771864d8990a904f087f85b848b 100644
--- a/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/state_draft.xml
+++ b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/state_draft.xml
@@ -16,12 +16,14 @@
             <key> <string>categories</string> </key>
             <value>
               <tuple>
-                <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_network</string>
+                <string>destination/portal_workflow/person_slap_interface_workflow/transition_notify</string>
                 <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_compute_node</string>
+                <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_network</string>
                 <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_organisation</string>
                 <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_project</string>
                 <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_site</string>
                 <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_software_instance</string>
+                <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_support</string>
                 <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_token</string>
               </tuple>
             </value>
diff --git a/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/state_open_order_created.xml b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/state_open_order_created.xml
index d70a0055894e874e54a0fe16c77a3a11fadf86e2..c292d9d1a528db081a2922bde2d4d4e0971985c1 100644
--- a/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/state_open_order_created.xml
+++ b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/state_open_order_created.xml
@@ -17,10 +17,14 @@
             <value>
               <tuple>
                 <string>destination/portal_workflow/person_slap_interface_workflow/transition_draft</string>
+                <string>destination/portal_workflow/person_slap_interface_workflow/transition_notify</string>
                 <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_compute_node</string>
+                <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_network</string>
                 <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_organisation</string>
                 <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_project</string>
+                <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_site</string>
                 <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_software_instance</string>
+                <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_support</string>
                 <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_token</string>
               </tuple>
             </value>
diff --git a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/interaction_WebMessage_setFollowUp.xml b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/transition_notify.xml
similarity index 52%
rename from master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/interaction_WebMessage_setFollowUp.xml
rename to master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/transition_notify.xml
index e0f82cf7da2adc5186697bf9b80c32164169d03e..922828587a1c8a088f4cf06d3e6770a2abacde8e 100644
--- a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/interaction_WebMessage_setFollowUp.xml
+++ b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/transition_notify.xml
@@ -2,61 +2,61 @@
 <ZopeData>
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
-      <global name="Interaction Workflow Interaction" module="erp5.portal_type"/>
+      <global name="Workflow Transition" module="erp5.portal_type"/>
     </pickle>
     <pickle>
       <dictionary>
         <item>
-            <key> <string>categories</string> </key>
+            <key> <string>action</string> </key>
             <value>
-              <tuple>
-                <string>before_commit_script/portal_workflow/slapos_erp5_interaction_workflow/script_WebMessage_stopAndReopenTicket</string>
-              </tuple>
+              <none/>
             </value>
         </item>
         <item>
-            <key> <string>description</string> </key>
+            <key> <string>action_name</string> </key>
             <value>
               <none/>
             </value>
         </item>
         <item>
-            <key> <string>id</string> </key>
-            <value> <string>interaction_WebMessage_setFollowUp</string> </value>
-        </item>
-        <item>
-            <key> <string>portal_type</string> </key>
-            <value> <string>Interaction Workflow Interaction</string> </value>
-        </item>
-        <item>
-            <key> <string>portal_type_filter</string> </key>
+            <key> <string>categories</string> </key>
             <value>
               <tuple>
-                <string>Web Message</string>
+                <string>action_type/workflow</string>
+                <string>before_script/portal_workflow/person_slap_interface_workflow/script_Person_checkConsistency</string>
+                <string>after_script/portal_workflow/person_slap_interface_workflow/script_Person_notify</string>
               </tuple>
             </value>
         </item>
         <item>
-            <key> <string>portal_type_group_filter</string> </key>
+            <key> <string>description</string> </key>
             <value>
-              <tuple/>
+              <none/>
             </value>
         </item>
         <item>
-            <key> <string>temporary_document_disallowed</string> </key>
-            <value> <int>0</int> </value>
+            <key> <string>guard_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
         </item>
         <item>
-            <key> <string>trigger_method_id</string> </key>
+            <key> <string>icon</string> </key>
             <value>
-              <tuple>
-                <string>_setFollowUp*</string>
-              </tuple>
+              <none/>
             </value>
         </item>
         <item>
-            <key> <string>trigger_once_per_transaction</string> </key>
-            <value> <int>1</int> </value>
+            <key> <string>id</string> </key>
+            <value> <string>transition_notify</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Transition</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Notify</string> </value>
         </item>
         <item>
             <key> <string>trigger_type</string> </key>
diff --git a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/interaction_SupportRequest_setSpecialise.xml b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/transition_request_support.xml
similarity index 52%
rename from master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/interaction_SupportRequest_setSpecialise.xml
rename to master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/transition_request_support.xml
index d2f2bf87e0f79e43283b3156ad454bb0e35b7efc..7054f62316acfae99b4a18270df1c7a7732d55bd 100644
--- a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/interaction_SupportRequest_setSpecialise.xml
+++ b/master/bt5/slapos_cloud/WorkflowTemplateItem/portal_workflow/person_slap_interface_workflow/transition_request_support.xml
@@ -2,61 +2,61 @@
 <ZopeData>
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
-      <global name="Interaction Workflow Interaction" module="erp5.portal_type"/>
+      <global name="Workflow Transition" module="erp5.portal_type"/>
     </pickle>
     <pickle>
       <dictionary>
         <item>
-            <key> <string>categories</string> </key>
+            <key> <string>action</string> </key>
             <value>
-              <tuple>
-                <string>before_commit_script/portal_workflow/slapos_erp5_interaction_workflow/script_SupportRequest_createInitialWebMessage</string>
-              </tuple>
+              <none/>
             </value>
         </item>
         <item>
-            <key> <string>description</string> </key>
+            <key> <string>action_name</string> </key>
             <value>
               <none/>
             </value>
         </item>
         <item>
-            <key> <string>id</string> </key>
-            <value> <string>interaction_SupportRequest_setSpecialise</string> </value>
-        </item>
-        <item>
-            <key> <string>portal_type</string> </key>
-            <value> <string>Interaction Workflow Interaction</string> </value>
-        </item>
-        <item>
-            <key> <string>portal_type_filter</string> </key>
+            <key> <string>categories</string> </key>
             <value>
               <tuple>
-                <string>Support Request</string>
+                <string>action_type/workflow</string>
+                <string>before_script/portal_workflow/person_slap_interface_workflow/script_Person_checkConsistency</string>
+                <string>after_script/portal_workflow/person_slap_interface_workflow/script_Person_requestSupportRequest</string>
               </tuple>
             </value>
         </item>
         <item>
-            <key> <string>portal_type_group_filter</string> </key>
+            <key> <string>description</string> </key>
             <value>
-              <tuple/>
+              <none/>
             </value>
         </item>
         <item>
-            <key> <string>temporary_document_disallowed</string> </key>
-            <value> <int>0</int> </value>
+            <key> <string>guard_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
         </item>
         <item>
-            <key> <string>trigger_method_id</string> </key>
+            <key> <string>icon</string> </key>
             <value>
-              <tuple>
-                <string>_setSpecialise*</string>
-              </tuple>
+              <none/>
             </value>
         </item>
         <item>
-            <key> <string>trigger_once_per_transaction</string> </key>
-            <value> <int>1</int> </value>
+            <key> <string>id</string> </key>
+            <value> <string>transition_request_support</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Transition</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Request Support</string> </value>
         </item>
         <item>
             <key> <string>trigger_type</string> </key>
diff --git a/master/bt5/slapos_crm/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml b/master/bt5/slapos_crm/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
index e6770c795d96560355d33d831cea53ed51fa8bd1..78636ca96967d3f50074fc4b0ad197e255b6ac10 100644
--- a/master/bt5/slapos_crm/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
+++ b/master/bt5/slapos_crm/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
@@ -7,4 +7,8 @@
   <type>Regularisation Request</type>
   <workflow>edit_workflow, pricing_interaction_workflow, ticket_interaction_workflow, ticket_workflow</workflow>
  </chain>
+ <chain>
+  <type>Support Request</type>
+  <workflow>ticket_slap_interface_workflow</workflow>
+ </chain>
 </workflow_chain>
\ No newline at end of file
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.py
deleted file mode 100644
index d9eca0ba5747ccc98651433176618291404b27d7..0000000000000000000000000000000000000000
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.py
+++ /dev/null
@@ -1,59 +0,0 @@
-from DateTime import DateTime
-
-portal = context.getPortalObject()
-aggregate_value = portal.restrictedTraverse(source_relative_url)
-
-if aggregate_value.getPortalType() == "Compute Node":
-  destination_decision = aggregate_value.getSourceAdministration()
-elif aggregate_value.getPortalType() == "Software Instance":
-  destination_decision = aggregate_value.getSpecialiseValue().getDestinationSection()
-elif aggregate_value.getPortalType() == "Instance Tree":
-  destination_decision = aggregate_value.getDestinationSection()
-elif aggregate_value.getPortalType() == "Software Installation":
-  destination_decision = aggregate_value.getDestinationSection()
-else:
-  destination_decision = None
-
-if portal.ERP5Site_isSupportRequestCreationClosed(destination_decision):
-  # Stop ticket creation
-  return
-
-support_request_in_progress = portal.portal_catalog.getResultValue(
-  portal_type = 'Support Request',
-  title = title,
-  simulation_state = ["validated", "submitted", "suspended"],
-  default_aggregate_uid = aggregate_value.getUid(),
-)
-
-if support_request_in_progress is not None:
-  return support_request_in_progress
-
-support_request_in_progress = context.REQUEST.get("support_request_in_progress", None)
-
-if support_request_in_progress is not None:
-  support_request = portal.restrictedTraverse(support_request_in_progress, None)
-  if support_request and support_request.getTitle() == title and \
-      support_request.getAggregateUid() == aggregate_value.getUid():
-    return portal.restrictedTraverse(support_request_in_progress)
-
-# Ensure resoure is Monitoring
-resource = portal.service_module.\
-                  slapos_crm_monitoring.getRelativeUrl()
-
-support_request = portal.restrictedTraverse(
-        portal.portal_preferences.getPreferredSupportRequestTemplate())\
-         .Base_createCloneDocument(batch_mode=1)
-
-support_request.edit(
-    title = title,
-    description = description,
-    start_date = DateTime(),
-    destination_decision=destination_decision,
-    aggregate_value = aggregate_value,
-    resource=resource
-  )
-support_request.validate()
-
-context.REQUEST.set("support_request_in_progress", support_request.getRelativeUrl())
-
-return support_request
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ComputeNode_checkAndUpdateAllocationScope.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ComputeNode_checkAndUpdateAllocationScope.py
index aeeadfb914c667e5252a6599e6c5bf2a40494757..59a78845f142acf77f6e98ed87dd13613870044c 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ComputeNode_checkAndUpdateAllocationScope.py
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ComputeNode_checkAndUpdateAllocationScope.py
@@ -29,11 +29,12 @@ request_title = 'Allocation scope of %s changed to %s' % (compute_node_reference
 request_description = 'Allocation scope has been changed to ' \
                      '%s for %s' % (target_allocation_scope, compute_node_reference)
 
-support_request = context.Base_generateSupportRequestForSlapOS(
-               request_title,
-               request_description,
-               compute_node.getRelativeUrl()
-             )
+person.notify(support_request_title=request_title,
+              support_request_description=request_description,
+              aggregate=context.getRelativeUrl())
+
+support_request_relative_url = context.REQUEST.get("support_request_relative_url")
+support_request = portal.restrictedTraverse(support_request_relative_url)
 
 if support_request is not None:
   if support_request.getSimulationState() != "validated":
@@ -53,8 +54,8 @@ if support_request is not None:
     message = notification_message.asText(
               substitution_method_parameter_dict={'mapping_dict': mapping_dict})
 
-  event = support_request.SupportRequest_trySendNotificationMessage(
-           request_title, message, person.getRelativeUrl())
+  support_request.notify(message_title=request_title, message=message)
+  event = support_request.REQUEST.get("ticket_notified_item")
 
   if event is not None:
     # event added, suspend ticket
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ComputeNode_checkSoftwareInstallationState.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ComputeNode_checkSoftwareInstallationState.py
index 2940a6a28afea1428b4c6a5e47da08f666bb6fd7..9e92a74ac6e6dc2eb35d93ad917feba5e5425378 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ComputeNode_checkSoftwareInstallationState.py
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ComputeNode_checkSoftwareInstallationState.py
@@ -1,12 +1,11 @@
 from DateTime import DateTime
 portal = context.getPortalObject()
 
-if portal.ERP5Site_isSupportRequestCreationClosed():
-  # Stop ticket creation
-  return
-
-if context.getMonitorScope() == "disabled":
-  return
+person = context.getSourceAdministrationValue(portal_type="Person")
+if not person or \
+   context.getMonitorScope() == "disabled" or \
+   portal.ERP5Site_isSupportRequestCreationClosed():
+  return 
 
 software_installation_list = portal.portal_catalog(
       portal_type='Software Installation',
@@ -50,15 +49,13 @@ for software_installation in software_installation_list:
         (software_installation.getUrlString(), compute_node_title, software_installation.getCreationDate())
 
   if should_notify:
-    support_request = context.Base_generateSupportRequestForSlapOS(
-      ticket_title,
-      description,
-      software_installation.getRelativeUrl()
-    )
+    person.notify(support_request_title=ticket_title,
+              support_request_description=description,
+              aggregate=software_installation.getRelativeUrl())
 
-    person = context.getSourceAdministrationValue(portal_type="Person")
-    if not person:
-      return support_request
+    support_request = context.REQUEST.get("support_request_relative_url")
+    if support_request is None:
+      return
 
     # Send Notification message
     notification_reference = 'slapos-crm-compute_node_software_installation_state.notification'
@@ -75,10 +72,7 @@ for software_installation in software_installation_list:
       message = notification_message.asText(
               substitution_method_parameter_dict={'mapping_dict':mapping_dict})
 
-    support_request.SupportRequest_trySendNotificationMessage(
-                ticket_title,
-                message, person.getRelativeUrl())
-
+    support_request.notify(message_title=ticket_title, message=message)
     support_request_list.append(support_request)
 
 return support_request_list
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ComputeNode_checkState.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ComputeNode_checkState.py
index 0b6887dcdcdf1576a07852717f632544f7091391..519caaf5f84cbf531091f45602a8e4e5c9fa6a08 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ComputeNode_checkState.py
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/ComputeNode_checkState.py
@@ -1,12 +1,11 @@
 from DateTime import DateTime
 portal = context.getPortalObject()
 
-if portal.ERP5Site_isSupportRequestCreationClosed():
-  # Stop ticket creation
-  return
-
-if context.getMonitorScope() == "disabled":
-  return
+person = context.getSourceAdministrationValue(portal_type="Person")
+if not person or \
+   context.getMonitorScope() == "disabled" or \
+   portal.ERP5Site_isSupportRequestCreationClosed():
+  return 
 
 if context.getAllocationScope("open").startswith("close"):
   context.setMonitorScope("disabled")
@@ -18,7 +17,6 @@ ticket_title = "[MONITORING] Lost contact with compute_node %s" % reference
 description = ""
 last_contact = "No Contact Information"
 
-
 d = context.getAccessStatus()
 # Ignore if data isn't present.
 if d.get("no_data") == 1:
@@ -33,20 +31,19 @@ else:
     # Nothing to notify.
     return  
 
-support_request = context.Base_generateSupportRequestForSlapOS(
-  ticket_title,
-  description,
-  context.getRelativeUrl()
-)
+person.notify(support_request_title=ticket_title,
+              support_request_description=description,
+              aggregate=context.getRelativeUrl())
 
-person = context.getSourceAdministrationValue(portal_type="Person")
-if not person:
-  return support_request
+support_request_relative_url = context.REQUEST.get("support_request_relative_url")
+if support_request_relative_url is None:
+  return
+
+support_request = portal.restrictedTraverse(support_request_relative_url)
 
 # Send Notification message
-notification_reference = 'slapos-crm-compute_node_check_state.notification'
 notification_message = portal.portal_notifications.getDocumentValue(
-                reference=notification_reference)
+  reference='slapos-crm-compute_node_check_state.notification')
 
 if notification_message is None:
   message = """%s""" % description
@@ -55,10 +52,8 @@ else:
                   'compute_node_id':reference,
                   'last_contact':last_contact}
   message = notification_message.asText(
-            substitution_method_parameter_dict={'mapping_dict':mapping_dict})
+            substitution_method_parameter_dict={'mapping_dict': mapping_dict})
+
+support_request.notify(message_title=ticket_title, message=message)
 
-support_request.SupportRequest_trySendNotificationMessage(
-            ticket_title,
-            message, person.getRelativeUrl())
-              
 return support_request
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/InstanceTree_createSupportRequestEvent.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/InstanceTree_createSupportRequestEvent.py
index b5f36c59657ac86ab21bf04d55f0b53b6f476b3c..10037b2ca9ca552a006250f37eface165b499272 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/InstanceTree_createSupportRequestEvent.py
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/InstanceTree_createSupportRequestEvent.py
@@ -1,5 +1,11 @@
 portal = context.getPortalObject()
 
+
+person = context.getDestinationSectionValue()
+if person is None or portal.ERP5Site_isSupportRequestCreationClosed(person.getRelativeUrl()):
+  # Stop ticket creation
+  return
+
 ticket_title = "Instance Tree %s is failing." % context.getTitle()
 error_message = instance.SoftwareInstance_hasReportedError(include_message=True)
 
@@ -10,27 +16,23 @@ if error_message:
 else:
   error_message = "No message!"
 
-support_request = context.Base_generateSupportRequestForSlapOS(
-  ticket_title,
-  description,
-  context.getRelativeUrl())
+person.notify(support_request_title=ticket_title,
+              support_request_description=description,
+              aggregate=context.getRelativeUrl())
 
-if support_request is None:
+support_request_relative_url = context.REQUEST.get("support_request_relative_url")
+if support_request_relative_url is None:
   return
 
-person = context.getDestinationSectionValue(portal_type="Person")
-if not person:
-  return
+support_request = portal.restrictedTraverse(support_request_relative_url)
 
 if support_request.getSimulationState() not in ["validated", "suspended"]:
   support_request.validate()
 
 # Send Notification message
 message = description
-
-notification_reference = notification_message_reference
 notification_message = portal.portal_notifications.getDocumentValue(
-                 reference=notification_reference)
+                 reference=notification_message_reference)
 if notification_message is not None:
   mapping_dict = {'instance_tree_title':context.getTitle(),
                   'instance': instance.getTitle(),
@@ -39,5 +41,5 @@ if notification_message is not None:
   message = notification_message.asText(
               substitution_method_parameter_dict={'mapping_dict':mapping_dict})
 
-return support_request.SupportRequest_trySendNotificationMessage(
-              ticket_title, message, person.getRelativeUrl())
+support_request.notify(message_title=ticket_title, message=message)
+return context.REQUEST.get("ticket_notified_item")
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.py
deleted file mode 100644
index 1359ecde5aac327bd8672e19b3503a4a15f01eaf..0000000000000000000000000000000000000000
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_trySendNotificationMessage.py
+++ /dev/null
@@ -1,41 +0,0 @@
-support_request = context
-portal = context.getPortalObject()
-
-resource = portal.service_module.slapos_crm_information.getRelativeUrl()
-# create Web message if needed for this ticket
-last_event = context.portal_catalog.getResultValue(
-             title=message_title,
-             follow_up_uid=support_request.getUid(),
-             sort_on=[('delivery.start_date', 'DESC')],
-)
-if last_event:
-  # User has already been notified for this problem.
-  return last_event
-
-transactional_event = context.REQUEST.get("support_request_notified_item", None)
-
-if transactional_event is not None:
-  if (transactional_event.getFollowUpUid() == support_request.getUid()) and \
-    (transactional_event.getTitle() == message_title):
-    return transactional_event
-
-template = portal.restrictedTraverse(
-        portal.portal_preferences.getPreferredWebMessageTemplate())
-
-event = template.Base_createCloneDocument(batch_mode=1)
-event.edit(
-  title=message_title,
-  text_content=message,
-  start_date = DateTime(),
-  resource = resource,
-  source=support_request.getSource(),
-  destination=destination_relative_url,
-  follow_up=support_request.getRelativeUrl(),
-)
-event.stop()
-event.deliver()
-
-support_request.serialize()
-context.REQUEST.set("support_request_notified_item", event)
-
-return event
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_updateMonitoringDestroyRequestedState.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_updateMonitoringDestroyRequestedState.py
index 1396f2619520760fa48bc70c1b6b21c5bf2b999e..639f01feca73300a9f0cf4afe971d9e3d3201f83 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_updateMonitoringDestroyRequestedState.py
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_updateMonitoringDestroyRequestedState.py
@@ -1,35 +1,31 @@
 """ Close Support Request which are related to a Destroy Requested Instance. """
-
+portal = context.getPortalObject()
 
 if context.getSimulationState() == "invalidated":
   return
 
 document = context.getAggregateValue()
-
 if document is not None and document.getSlapState() == "destroy_requested":
   
   person = context.getDestinationDecision(portal_type="Person")
   if not person:
     return 
 
-  if context.getSimulationState() != "invalidated":
-    context.invalidate()
-
   # Send Notification message
   message = """ Closing this ticket as the Instance Tree was destroyed by the user. 
   """
 
-  notification_reference = "slapos-crm-support-request-close-destroyed-notification"
-  portal = context.getPortalObject()
-
   notification_message = portal.portal_notifications.getDocumentValue(
-                 reference=notification_reference)
+    reference="slapos-crm-support-request-close-destroyed-notification")
 
   if notification_message is not None:
-    mapping_dict = {'instance_tree_title':document.getTitle()}
+    mapping_dict = {'instance_tree_title': document.getTitle()}
 
     message = notification_message.asText(
               substitution_method_parameter_dict={'mapping_dict':mapping_dict})
-  
-  return context.SupportRequest_trySendNotificationMessage(
-              "Instance Tree was destroyed was destroyed by the user", message, person)
+
+  context.notify(message_title="Instance Tree was destroyed was destroyed by the user",
+              message=message)
+
+  context.invalidate()
+  return context.REQUEST.get("ticket_notified_item")
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_updateMonitoringState.py b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_updateMonitoringState.py
index ead0556970d690a9c40269e50334080866819fff..dfa470efd547e9ba7b5c7a91ab18c5905b6864af 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_updateMonitoringState.py
+++ b/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/SupportRequest_updateMonitoringState.py
@@ -2,7 +2,6 @@ if context.getSimulationState() == "invalidated":
   return
 
 document = context.getAggregateValue(portal_type="Instance Tree")
-
 if document is None:
   return 
 
diff --git a/master/bt5/slapos_crm/TestTemplateItem/portal_components/test.erp5.testSlapOSCRMSkins.py b/master/bt5/slapos_crm/TestTemplateItem/portal_components/test.erp5.testSlapOSCRMSkins.py
index a2417d393f57035e546aef90e2b540d3245d3dd6..7a6f685e719ce442822be9d3145e1f5d5b572211 100644
--- a/master/bt5/slapos_crm/TestTemplateItem/portal_components/test.erp5.testSlapOSCRMSkins.py
+++ b/master/bt5/slapos_crm/TestTemplateItem/portal_components/test.erp5.testSlapOSCRMSkins.py
@@ -27,8 +27,6 @@ from erp5.component.test.SlapOSTestCaseMixin import \
 from DateTime import DateTime
 from App.Common import rfc1123_date
 from Products.ERP5Type.Cache import DEFAULT_CACHE_SCOPE
-
-from Products.ERP5Type.tests.utils import createZODBPythonScript
 import json
 
 import feedparser
@@ -655,13 +653,6 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin):
   'assert reference == "slapos-crm-compute_node_allocation_scope.notification"\n' \
   'return context.restrictedTraverse(' \
   'context.REQUEST["test_ComputeNodeNotAllowedAllocationScope_OpenPublic"])')
-  @simulate('SupportRequest_trySendNotificationMessage',
-            'message_title, message, destination_relative_url',
-  'context.portal_workflow.doActionFor(' \
-  'context, action="edit_action", ' \
-  'comment="Visited by SupportRequest_trySendNotificationMessage ' \
-  '%s %s %s" % (message_title, message, destination_relative_url))\n' \
-  'return 1')
   def test_ComputeNodeNotAllowedAllocationScope_OpenPublic(self):
     compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
     person = compute_node.getSourceAdministrationValue()
@@ -677,13 +668,14 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin):
     self.assertNotEqual(None, ticket)
     self.assertEqual(ticket.getSimulationState(), 'suspended')
 
-    self.assertEqual('Visited by SupportRequest_trySendNotificationMessage ' \
-      '%s %s %s' % \
-      ('Allocation scope of %s changed to %s' % (compute_node.getReference(),
-                                                  'open/personal'),
-       'Test NM content\n%s\n' % compute_node.getReference(), person.getRelativeUrl()),
-      ticket.workflow_history['edit_workflow'][-1]['comment'])
+    event_list = ticket.getFollowUpRelatedValueList()
+    self.assertEqual(len(event_list), 1)
+    event = event_list[0]
 
+    self.assertEqual(event.getTitle(),
+      'Allocation scope of %s changed to %s' % (compute_node.getReference(), 'open/personal'))
+    self.assertIn(compute_node.getReference(), event.getTextContent())
+    self.assertEqual(event.getDestination(), person.getRelativeUrl())
 
   @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
   @simulate('NotificationTool_getDocumentValue',
@@ -691,13 +683,6 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin):
   'assert reference == "slapos-crm-compute_node_allocation_scope.notification"\n' \
   'return context.restrictedTraverse(' \
   'context.REQUEST["test_ComputeNodeNotAllowedAllocationScope_OpenFriend"])')
-  @simulate('SupportRequest_trySendNotificationMessage',
-            'message_title, message, destination_relative_url',
-  'context.portal_workflow.doActionFor(' \
-  'context, action="edit_action", ' \
-  'comment="Visited by SupportRequest_trySendNotificationMessage ' \
-  '%s %s %s" % (message_title, message, destination_relative_url))\n' \
-  'return 1')
   def test_ComputeNodeNotAllowedAllocationScope_OpenFriend(self):
     compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
     person = compute_node.getSourceAdministrationValue()
@@ -712,12 +697,15 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin):
     self.tic()
     self.assertEqual(compute_node.getAllocationScope(), 'open/personal')
     self.assertEqual(ticket.getSimulationState(), 'suspended')
-    self.assertEqual('Visited by SupportRequest_trySendNotificationMessage ' \
-      '%s %s %s' % \
-      ('Allocation scope of %s changed to %s' % (compute_node.getReference(),
-                                                  'open/personal'),
-       'Test NM content\n%s\n' % compute_node.getReference(), person.getRelativeUrl()),
-      ticket.workflow_history['edit_workflow'][-1]['comment'])
+
+    event_list = ticket.getFollowUpRelatedValueList()
+    self.assertEqual(len(event_list), 1)
+    event = event_list[0]
+
+    self.assertEqual(event.getTitle(),
+      'Allocation scope of %s changed to %s' % (compute_node.getReference(), 'open/personal'))
+    self.assertIn(compute_node.getReference(), event.getTextContent())
+    self.assertEqual(event.getDestination(), person.getRelativeUrl())
 
   @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
   @simulate('ComputeNode_hasContactedRecently', '*args, **kwargs','return False')
@@ -726,13 +714,6 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin):
   'assert reference == "slapos-crm-compute-node-allocation-scope-closed.notification"\n' \
   'return context.restrictedTraverse(' \
   'context.REQUEST["test_ComputeNodeToCloseAllocationScope_OpenPersonal"])')
-  @simulate('SupportRequest_trySendNotificationMessage',
-            'message_title, message, destination_relative_url',
-  'context.portal_workflow.doActionFor(' \
-  'context, action="edit_action", ' \
-  'comment="Visited by SupportRequest_trySendNotificationMessage ' \
-  '%s %s %s" % (message_title, message, destination_relative_url))\n' \
-  'return 1')
   def test_ComputeNodeToCloseAllocationScope_OpenPersonal(self):
     compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
     person = compute_node.getSourceAdministrationValue()
@@ -747,12 +728,16 @@ class TestSlapOSComputeNode_notifyWrongAllocationScope(TestCRMSkinsMixin):
 
     self.assertEqual('suspended', support_request.getSimulationState())
     self.assertEqual(compute_node.getAllocationScope(), target_allocation_scope)
-    self.assertEqual('Visited by SupportRequest_trySendNotificationMessage ' \
-      '%s %s %s' % \
-      ('Allocation scope of %s changed to %s' % (compute_node.getReference(),
-                                                  target_allocation_scope),
-       'Test NM content\n%s\n' % compute_node.getReference(), person.getRelativeUrl()),
-      support_request.workflow_history['edit_workflow'][-1]['comment'])
+    
+    event_list = support_request.getFollowUpRelatedValueList()
+    self.assertEqual(len(event_list), 1)
+    event = event_list[0]
+
+    self.assertEqual(event.getTitle(),
+      'Allocation scope of %s changed to %s' % \
+        (compute_node.getReference(), target_allocation_scope))
+    self.assertIn(compute_node.getReference(), event.getTextContent())
+    self.assertEqual(event.getDestination(), person.getRelativeUrl())
 
   def test_ComputeNodeNormalAllocationScope_OpenPersonal(self):
     compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
@@ -988,189 +973,6 @@ class TestSlapOSisSupportRequestCreationClosed(TestCRMSkinsMixin):
     self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed())
 
 
-class TestSlapOSGenerateSupportRequestForSlapOS(TestCRMSkinsMixin):
-
-  def afterSetUp(self):
-    TestCRMSkinsMixin.afterSetUp(self)
-    self.tic()
-    self._cancelTestSupportRequestList()
-
-  def test_compute_node_Base_generateSupportRequestForSlapOS(self):
-    self._makeComputeNode()
-    title = "Test Support Request %s" % self.compute_node.getReference()
-    support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
-      title, title, self.compute_node.getRelativeUrl()
-    )
-    self.tic()
-
-    self.assertNotEqual(support_request, None)
-
-    self.assertEqual(support_request.getSimulationState(), "validated")
-    self.assertEqual(support_request.getRelativeUrl(),
-      self.portal.REQUEST.get("support_request_in_progress", None))
-
-    # The support request is added to compute_node owner.
-    self.assertEqual(support_request.getDestinationDecision(),
-                      self.compute_node.getSourceAdministration())
-    self.assertEqual(support_request.getTitle(), title)
-    self.assertEqual(support_request.getDescription(), title)
-    self.assertEqual(support_request.getAggregateValue(),
-                      self.compute_node)
-
-  def test_software_instance_Base_generateSupportRequestForSlapOS(self):
-    instance_tree = self._makeInstanceTree()
-    self._makeSoftwareInstance(instance_tree,
-                               self.generateNewSoftwareReleaseUrl())
-
-    instance = instance_tree.getSuccessorValue()
-    title = "Test Support Request %s" % instance.getReference()
-    support_request = instance.Base_generateSupportRequestForSlapOS(
-      title, title, instance.getRelativeUrl()
-    )
-    self.tic()
-
-    self.assertNotEqual(support_request, None)
-
-    self.assertEqual(support_request.getSimulationState(), "validated")
-    self.assertEqual(support_request.getRelativeUrl(),
-      self.portal.REQUEST.get("support_request_in_progress", None))
-
-    # The support request is added to compute_node owner.
-    self.assertEqual(support_request.getDestinationDecision(),
-                      instance_tree.getDestinationSection())
-    self.assertEqual(support_request.getTitle(), title)
-    self.assertEqual(support_request.getDescription(), title)
-    self.assertEqual(support_request.getAggregateValue(),
-                      instance)
-
-  def test_instance_tree_Base_generateSupportRequestForSlapOS(self):
-    instance_tree = self._makeInstanceTree()
-
-    title = "Test Support Request %s" % instance_tree.getReference()
-    support_request = instance_tree.Base_generateSupportRequestForSlapOS(
-      title, title, instance_tree.getRelativeUrl()
-    )
-    self.tic()
-
-    self.assertNotEqual(support_request, None)
-
-    self.assertEqual(support_request.getSimulationState(), "validated")
-    self.assertEqual(support_request.getRelativeUrl(),
-      self.portal.REQUEST.get("support_request_in_progress", None))
-
-    # The support request is added to compute_node owner.
-    self.assertEqual(support_request.getDestinationDecision(),
-                      instance_tree.getDestinationSection())
-
-    self.assertEqual(support_request.getTitle(), title)
-    self.assertEqual(support_request.getDescription(), title)
-    self.assertEqual(support_request.getAggregateValue(),
-                      instance_tree)
-
-  def test_software_installation_Base_generateSupportRequestForSlapOS(self):
-    software_installation = self._makeSoftwareInstallation()
-
-    title = "Test Support Request %s" % software_installation.generateNewId()
-    support_request = software_installation.Base_generateSupportRequestForSlapOS(
-      title, title, software_installation.getRelativeUrl()
-    )
-    self.tic()
-
-    self.assertNotEqual(support_request, None)
-
-    self.assertEqual(support_request.getSimulationState(), "validated")
-    self.assertEqual(support_request.getRelativeUrl(),
-      self.portal.REQUEST.get("support_request_in_progress", None))
-
-    # The support request is added to compute_node owner.
-    self.assertEqual(support_request.getDestinationDecision(),
-                      software_installation.getDestinationSection())
-
-    self.assertEqual(support_request.getTitle(), title)
-    self.assertEqual(support_request.getDescription(), title)
-    self.assertEqual(support_request.getAggregateValue(),
-                      software_installation)
-
-
-  def test_Base_generateSupportRequestForSlapOS_do_not_recreate_if_open(self):
-    self._makeComputeNode(owner=self.makePerson(user=0))
-    title = "Test Support Request %s" % self.compute_node.getReference()
-    support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
-      title, title, self.compute_node.getRelativeUrl()
-    )
-    self.tic()
-    self.portal.REQUEST.set("support_request_in_progress", None)
-
-    same_support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
-      title, title, self.compute_node.getRelativeUrl()
-    )
-
-    self.assertEqual(support_request, same_support_request)
-
-
-  def test_Base_generateSupportRequestForSlapOS_do_not_recreate_if_suspended(self):
-    self._makeComputeNode(owner=self.makePerson(user=0))
-    title = "Test Support Request %s" % self.compute_node.getReference()
-    support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
-      title, title, self.compute_node.getRelativeUrl()
-    )
-
-    support_request.suspend()
-    self.tic()
-    self.portal.REQUEST.set("support_request_in_progress", None)
-
-    same_support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
-      title, title, self.compute_node.getRelativeUrl()
-    )
-
-    self.assertEqual(support_request, same_support_request)
-
-  def test_Base_generateSupportRequestForSlapOS_recreate_if_closed(self):
-    self._makeComputeNode(owner=self.makePerson(user=0))
-    title = "Test Support Request %s" % self.compute_node.getReference()
-    support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
-      title, title, self.compute_node.getRelativeUrl())
-    self.tic()
-
-    support_request.invalidate()
-    self.tic()
-
-    self.portal.REQUEST.set("support_request_in_progress", None)
-
-    support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
-      title, title, self.compute_node.getRelativeUrl()
-    )
-    self.tic()
-
-    self.assertNotEqual(support_request, None)
-
-  def test_Base_generateSupportRequestForSlapOS_recreate(self):
-    self._makeComputeNode(owner=self.makePerson(user=0))
-    title = "Test Support Request %s" % self.compute_node.getRelativeUrl()
-    support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
-      title, title, self.compute_node.getRelativeUrl())
-
-    same_support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
-      title, title, self.compute_node.getRelativeUrl()
-    )
-
-    self.assertEqual(support_request, same_support_request)
-
-  def test_Base_generateSupportRequestForSlapOS_inprogress(self):
-    self._makeComputeNode(owner=self.makePerson(user=0))
-    title = "Test Support Request %s" % self.compute_node.getRelativeUrl()
-    support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
-      title, title, self.compute_node.getRelativeUrl())
-
-    in_progress = support_request.getRelativeUrl()
-    self.portal.REQUEST.set("support_request_in_progress", in_progress)
-
-    title = "Test Support Request %s" % self.compute_node.getRelativeUrl()
-    support_request = self.compute_node.Base_generateSupportRequestForSlapOS(
-      title, title, self.compute_node.getRelativeUrl())
-
-    self.assertEqual(support_request.getRelativeUrl(), in_progress)
-
 class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
 
   def beforeTearDown(self):
@@ -1181,11 +983,6 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
     TestCRMSkinsMixin.afterSetUp(self)
     self._cancelTestSupportRequestList("% TESTCOMPT-%")
 
-  def _makeSupportRequest(self):
-    return self.portal.restrictedTraverse(
-        self.portal.portal_preferences.getPreferredSupportRequestTemplate()).\
-       Base_createCloneDocument(batch_mode=1)
-
   def _makeNotificationMessage(self, reference):
     notification_message = self.portal.notification_message_module.newContent(
       portal_type="Notification Message",
@@ -1205,56 +1002,36 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
     )
     return support_request
 
-  def _simulateBase_generateSupportRequestForSlapOS(self):
-    script_name = 'Base_generateSupportRequestForSlapOS'
-    if script_name in self.portal.portal_skins.custom.objectIds():
-      raise ValueError('Precondition failed: %s exists in custom' % script_name)
-    createZODBPythonScript(self.portal.portal_skins.custom,
-      script_name,
-      '*args, **kw',
-      '# Script body\n'
-"""return context.getPortalObject().REQUEST['_simulateBase_generateSupportRequestForSlapOS']""")
-    transaction.commit()
-
   @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
   def test_ComputeNode_checkState_call_support_request(self):
     compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
     try:
-      self.pinDateTime(DateTime()-1.1)
+      d = DateTime() - 1.1
+      self.pinDateTime(d)
       compute_node.setAccessStatus("#access ")
     finally:
       self.unpinDateTime()
 
-    self._simulateBase_generateSupportRequestForSlapOS()
-    support_request = self._makeSupportRequest()
-    self.portal.REQUEST.set('_simulateBase_generateSupportRequestForSlapOS',
-                               support_request)
-
-    try:
-      compute_node_support_request = compute_node.ComputeNode_checkState()
-    finally:
-      self._dropScript("Base_generateSupportRequestForSlapOS")
-
-    self.assertEqual(support_request,
-      compute_node_support_request)
-
+    compute_node_support_request = compute_node.ComputeNode_checkState()
+    self.assertNotEqual(compute_node_support_request, None)
+    self.assertIn("[MONITORING] Lost contact with compute_node",
+      compute_node_support_request.getTitle())
+    self.assertIn("has not contacted the server for more than 30 minutes",
+      compute_node_support_request.getDescription())
+    self.assertIn(d.strftime("%Y/%m/%d %H:%M:%S"),
+      compute_node_support_request.getDescription())
 
   @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
   def test_ComputeNode_checkState_empty_cache(self):
     compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
-
-    self._simulateBase_generateSupportRequestForSlapOS()
-    support_request = self._makeSupportRequest()
-    self.portal.REQUEST.set('_simulateBase_generateSupportRequestForSlapOS',
-                               support_request)
-
-    try:
-      compute_node_support_request = compute_node.ComputeNode_checkState()
-    finally:
-      self._dropScript("Base_generateSupportRequestForSlapOS")
-
-    self.assertEqual(support_request,
-      compute_node_support_request)
+    compute_node_support_request = compute_node.ComputeNode_checkState()
+    
+    compute_node_support_request = compute_node.ComputeNode_checkState()
+    self.assertNotEqual(compute_node_support_request, None)
+    self.assertIn("[MONITORING] Lost contact with compute_node",
+      compute_node_support_request.getTitle())
+    self.assertIn("has not contacted the server (No Contact Information)",
+      compute_node_support_request.getDescription())
 
   @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
   @simulate('NotificationTool_getDocumentValue',
@@ -1262,12 +1039,6 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
   'assert reference == "slapos-crm-compute_node_check_state.notification"\n' \
   'return context.restrictedTraverse(' \
   'context.REQUEST["test_ComputeNode_checkState_notify"])')
-  @simulate('SupportRequest_trySendNotificationMessage',
-            'message_title, message, destination_relative_url',
-  'context.portal_workflow.doActionFor(' \
-  'context, action="edit_action", ' \
-  'comment="Visited by SupportRequest_trySendNotificationMessage ' \
-  '%s %s %s" % (message_title, message, destination_relative_url))')
   def test_ComputeNode_checkState_notify(self):
     compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
     person = compute_node.getSourceAdministrationValue()
@@ -1286,14 +1057,15 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
 
     ticket_title = "[MONITORING] Lost contact with compute_node %s" % compute_node.getReference()
     ticket = self._getGeneratedSupportRequest(compute_node.getUid(), ticket_title)
+
     self.assertNotEqual(ticket, None)
-    self.assertEqual('Visited by SupportRequest_trySendNotificationMessage ' \
-      '%s %s %s' % ( \
-      ticket_title,
-      'Test NM content\n%s\n' % compute_node.getReference(),
-      person.getRelativeUrl()),
-      ticket.workflow_history['edit_workflow'][-1]['comment'])
+    event_list = ticket.getFollowUpRelatedValueList()
+    self.assertEqual(len(event_list), 1)
+    event = event_list[0]
 
+    self.assertEqual(event.getTitle(), ticket.getTitle())
+    self.assertIn(compute_node.getReference(), event.getTextContent())
+    self.assertEqual(event.getDestination(), person.getRelativeUrl())
 
   @simulate('ERP5Site_isSupportRequestCreationClosed', '*args, **kwargs','return 0')
   @simulate('NotificationTool_getDocumentValue',
@@ -1301,12 +1073,6 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
   'assert reference == "slapos-crm-compute_node_check_state.notification"\n' \
   'return context.restrictedTraverse(' \
   'context.REQUEST["test_ComputeNode_checkState_empty_cache_notify"])')
-  @simulate('SupportRequest_trySendNotificationMessage',
-            'message_title, message, destination_relative_url',
-  'context.portal_workflow.doActionFor(' \
-  'context, action="edit_action", ' \
-  'comment="Visited by SupportRequest_trySendNotificationMessage ' \
-  '%s %s %s" % (message_title, message, destination_relative_url))')
   def test_ComputeNode_checkState_empty_cache_notify(self):
     compute_node = self._makeComputeNode(owner=self.makePerson(user=0))[0]
     person = compute_node.getSourceAdministrationValue()
@@ -1320,13 +1086,13 @@ class TestSlapOSComputeNode_CheckState(TestCRMSkinsMixin):
     ticket_title = "[MONITORING] Lost contact with compute_node %s" % compute_node.getReference()
     ticket = self._getGeneratedSupportRequest(compute_node.getUid(), ticket_title)
     self.assertNotEqual(ticket, None)
-    self.assertEqual('Visited by SupportRequest_trySendNotificationMessage ' \
-      '%s %s %s' % ( \
-      ticket_title,
-      'Test NM content\n%s\n' % compute_node.getReference(),
-      person.getRelativeUrl()),
-      ticket.workflow_history['edit_workflow'][-1]['comment'])
+    event_list = ticket.getFollowUpRelatedValueList()
+    self.assertEqual(len(event_list), 1)
+    event = event_list[0]
 
+    self.assertEqual(event.getTitle(), ticket.getTitle())
+    self.assertIn(compute_node.getReference(), event.getTextContent())
+    self.assertEqual(event.getDestination(), person.getRelativeUrl())
 
 class TestSlapOSInstanceTree_createSupportRequestEvent(SlapOSTestCaseMixin):
 
@@ -1341,8 +1107,7 @@ class TestSlapOSInstanceTree_createSupportRequestEvent(SlapOSTestCaseMixin):
     return notification_message.getRelativeUrl()
 
   def _makeInstanceTree(self):
-    person = self.portal.person_module.template_member\
-         .Base_createCloneDocument(batch_mode=1)
+    person = self.makePerson(user=1)
     instance_tree = self.portal\
       .instance_tree_module.template_instance_tree\
       .Base_createCloneDocument(batch_mode=1)
@@ -1371,12 +1136,6 @@ class TestSlapOSInstanceTree_createSupportRequestEvent(SlapOSTestCaseMixin):
   'assert reference == "test-slapos-crm-check.notification"\n' \
   'return context.restrictedTraverse(' \
   'context.REQUEST["testInstanceTree_createSupportRequestEvent"])')
-  @simulate('SupportRequest_trySendNotificationMessage',
-            'message_title, message, destination_relative_url',
-  'context.portal_workflow.doActionFor(' \
-  'context, action="edit_action", ' \
-  'comment="Visited by SupportRequest_trySendNotificationMessage ' \
-  '%s %s %s" % (message_title, message, destination_relative_url))')
   def testInstanceTree_createSupportRequestEvent(self):
     instance_tree = self._makeInstanceTree()
     person =  instance_tree.getDestinationSectionValue()
@@ -1392,12 +1151,14 @@ class TestSlapOSInstanceTree_createSupportRequestEvent(SlapOSTestCaseMixin):
       instance_tree.getUid())
     self.assertNotEqual(ticket, None)
     self.assertEqual(ticket.getSimulationState(), "validated")
-    self.assertEqual('Visited by SupportRequest_trySendNotificationMessage ' \
-      '%s %s %s' % ( \
-      ticket_title,
-      'Test NM content\n%s\n' % instance_tree.getReference(),
-      person.getRelativeUrl()),
-      ticket.workflow_history['edit_workflow'][-1]['comment'])
+    self.assertNotEqual(ticket, None)
+    event_list = ticket.getFollowUpRelatedValueList()
+    self.assertEqual(len(event_list), 1)
+    event = event_list[0]
+
+    self.assertEqual(event.getTitle(), ticket_title)
+    self.assertIn(instance_tree.getReference(), event.getTextContent())
+    self.assertEqual(event.getDestination(), person.getRelativeUrl())
 
     ticket.suspend()
     self.tic()
@@ -1734,95 +1495,6 @@ class TestSlapOSHasError(SlapOSTestCaseMixin):
         None,
         instance_tree.InstanceTree_checkSoftwareInstanceState())
 
-class TestSupportRequestTrySendNotificationMessage(SlapOSTestCaseMixin):
-
-  def test_SupportRequest_trySendNotificationMessage(self):
-    self._makeComputeNode(owner=self.makePerson(user=0))
-    person = self.compute_node.getSourceAdministrationValue()
-    title = "Test Support Request %s" % self.compute_node.getReference()
-    text_content='Test NM content<br/>%s<br/>' % self.compute_node.getReference()
-
-    support_request = self.portal.support_request_module.newContent(\
-            title=title, description=title,
-            destination_decision=self.compute_node.getSourceAdministration(),
-            aggregate_value=self.compute_node.getRelativeUrl())
-    support_request.validate()
-    self.tic()
-
-    first_event = support_request.SupportRequest_trySendNotificationMessage(
-      message_title=title, message=text_content,
-      destination_relative_url=person.getRelativeUrl()
-    )
-    self.assertNotEqual(first_event, None)
-
-    self.tic()
-    self.assertEqual(
-      support_request.getFollowUpRelatedList(),
-      [first_event.getRelativeUrl()])
-
-    self.assertEqual(title, first_event.getTitle())
-    self.assertEqual(text_content, first_event.getTextContent())
-    self.assertNotEqual(None, first_event.getStartDate())
-    self.assertEqual("service_module/slapos_crm_information",
-                      first_event.getResource())
-    self.assertEqual(first_event.getDestination(), person.getRelativeUrl())
-    self.assertEqual(first_event.getFollowUp(), support_request.getRelativeUrl())
-
-    event = support_request.SupportRequest_trySendNotificationMessage(
-      message_title=title, message=text_content,
-      destination_relative_url=person.getRelativeUrl()
-    )
-    self.assertEqual(event, first_event)
-
-    self.assertEqual(title, event.getTitle())
-    self.assertEqual(text_content, event.getTextContent())
-    self.assertNotEqual(None, event.getStartDate())
-    self.assertEqual("service_module/slapos_crm_information",
-                      event.getResource())
-    self.assertEqual(event.getDestination(), person.getRelativeUrl())
-
-    title += "__zz"
-    event = support_request.SupportRequest_trySendNotificationMessage(
-      message_title=title, message=text_content,
-      destination_relative_url=person.getRelativeUrl(),
-    )
-
-    self.assertEqual(event.getTitle(), title)
-    self.assertEqual(text_content, event.getTextContent())
-    self.assertNotEqual(None, event.getStartDate())
-    self.assertEqual("service_module/slapos_crm_information",
-                      event.getResource())
-    self.assertEqual(event.getDestination(), person.getRelativeUrl())
-
-    another_support_request = self.portal.support_request_module.newContent(\
-            title=title, description=title,
-            destination_decision=self.compute_node.getSourceAdministration(),
-            aggregate_value=self.compute_node.getRelativeUrl())
-    another_support_request.validate()
-    self.tic()
-
-    another_first_event = \
-      another_support_request.SupportRequest_trySendNotificationMessage(
-        message_title=title, message=text_content,
-        destination_relative_url=person.getRelativeUrl())
-
-    self.assertNotEqual(another_first_event, None)
-
-    self.tic()
-    self.assertEqual(
-      another_support_request.getFollowUpRelatedList(),
-      [another_first_event.getRelativeUrl()])
-
-    self.assertEqual(title, another_first_event.getTitle())
-    self.assertEqual(text_content, another_first_event.getTextContent())
-    self.assertNotEqual(None, another_first_event.getStartDate())
-    self.assertEqual("service_module/slapos_crm_information",
-                      another_first_event.getResource())
-    self.assertEqual(another_first_event.getDestination(), person.getRelativeUrl())
-    self.assertEqual(another_first_event.getFollowUp(),
-     another_support_request.getRelativeUrl())
-
-
 class TestSupportRequestUpdateMonitoringState(SlapOSTestCaseMixin):
 
   def _makeInstanceTree(self):
@@ -1873,10 +1545,6 @@ class TestSupportRequestUpdateMonitoringState(SlapOSTestCaseMixin):
       support_request.SupportRequest_updateMonitoringState())
 
   @simulate('ERP5Site_isSupportRequestCreationClosed', '','return 0')
-  @simulate('SupportRequest_trySendNotificationMessage',
-            "message_title, message, source_relative_url",
-     """assert "destroyed" in message
-return "Visited by SupportRequest_trySendNotificationMessage %s %s" % (message_title, source_relative_url)""")
   def testSupportRequest_updateMonitoringDestroyRequestedState(self):
     support_request = self._makeSupportRequest()
     self.assertEqual(None,
@@ -1887,20 +1555,29 @@ return "Visited by SupportRequest_trySendNotificationMessage %s %s" % (message_t
 
     support_request.setAggregateValue(
       self._makeComputeNode(owner=self.makePerson(user=0))[0])
+    support_request.setDestinationDecisionValue(self.makePerson(user=0))
     self.assertEqual(None,
       support_request.SupportRequest_updateMonitoringDestroyRequestedState())
 
     hs = self._makeInstanceTree()
     support_request.setAggregateValue(hs)
 
+    self.tic()
+
     hs.getSlapState = getFakeSlapState
     self.commit()
 
-    support_request.setDestinationDecisionValue(self.makePerson(user=0))
-    expected_text = """Visited by SupportRequest_trySendNotificationMessage Instance Tree was destroyed was destroyed by the user %s""" % support_request.getDestinationDecision()
-    self.assertEqual(expected_text,
+    self.assertNotEqual(None,
       support_request.SupportRequest_updateMonitoringDestroyRequestedState())
 
+    self.tic()
+    event_list = support_request.getFollowUpRelatedValueList()
+    self.assertEqual(len(event_list), 1)
+    event = event_list[0]
+
+    self.assertEqual(event.getTitle(), 'Instance Tree was destroyed was destroyed by the user')
+    self.assertEqual(event.getDestination(), support_request.getDestinationDecision())
+
     self.assertEqual("invalidated",
       support_request.getSimulationState())
 
diff --git a/master/bt5/slapos_crm/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudTicketSlapInterfaceWorkflow.py b/master/bt5/slapos_crm/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudTicketSlapInterfaceWorkflow.py
new file mode 100644
index 0000000000000000000000000000000000000000..77dbb3953e5726ebafd1f521bddc53be2c177d60
--- /dev/null
+++ b/master/bt5/slapos_crm/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudTicketSlapInterfaceWorkflow.py
@@ -0,0 +1,212 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin #, simulate
+import transaction
+
+class TestSlapOSCoreTicketSlapInterfaceWorkflow(SlapOSTestCaseMixin):
+
+  def afterSetUp(self):
+    SlapOSTestCaseMixin.afterSetUp(self)
+    portal = self.getPortalObject()
+
+    self.ticket_trade_condition = portal.sale_trade_condition_module.slapos_ticket_trade_condition
+
+    person_user = self.makePerson()
+    self.tic()
+
+    # Login as new user
+    self.login(person_user.getUserId())
+
+    new_person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
+    self.assertEqual(person_user.getRelativeUrl(), new_person.getRelativeUrl())
+
+    self.support_request = portal.support_request_module.newContent(
+      portal_type="Support Request",
+      destination_decision=person_user.getRelativeUrl(),
+      specialise=self.ticket_trade_condition.getRelativeUrl()
+    )
+
+    # Value set by the init
+    self.assertTrue(self.support_request.getReference().startswith("SR-"),
+      "Reference don't start with SR- : %s" % self.support_request.getReference())
+
+  def beforeTearDown(self):
+    transaction.abort()
+
+  def test_SupportRequest_approveRegistration_no_reference(self):
+    self.support_request.setReference(None)
+    self.assertRaises(ValueError, self.support_request.approveRegistration)
+
+  def test_SupportRequest_approveRegistration_already_validated(self):
+
+    # Login as admin since user cannot re-approve a validated project
+    self.login()
+    self.support_request.validate()
+    # Don't raise if support request is validated
+    self.assertEqual(self.support_request.approveRegistration(), None)
+
+  def test_SupportRequest_approveRegistration(self):
+    person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
+
+    self.support_request.approveRegistration()
+    self.tic()
+
+    self.logout()
+    self.login(person.getUserId())
+
+    self.assertEqual(self.support_request.getSimulationState(),
+      'validated')
+
+    self.assertEqual(self.support_request.getSourceSection(),
+      self.ticket_trade_condition.getSourceSection())
+    self.assertEqual(self.support_request.getSourceTrade(),
+      self.ticket_trade_condition.getSourceSection())
+    self.assertEqual(self.support_request.getSource(),
+      self.ticket_trade_condition.getSource())
+
+    self.assertNotEqual(self.support_request.getStartDate(),
+      None)
+
+    event = self.support_request.getCausalityValue()
+    self.assertNotEqual(event, None)
+
+    event_relative_url = self.support_request.REQUEST.get("event_relative_url")
+    self.assertEqual(event.getRelativeUrl(), event_relative_url)
+
+    self.assertEqual(event.getTitle(), self.support_request.getTitle())
+   
+  def test_SupportRequest_requestEvent_noParameter(self):
+    self.assertRaises(TypeError, self.support_request.requestEvent)
+    self.assertRaises(TypeError, self.support_request.requestEvent, event_title="A")
+    self.assertRaises(TypeError, self.support_request.requestEvent, event_content="A")
+
+  def test_SupportRequest_requestEvent(self):
+    person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
+
+    self.support_request.approveRegistration()
+    self.tic()
+
+    self.logout()
+    self.login(person.getUserId())
+
+    self.support_request.requestEvent(
+      event_title="A",
+      event_content="B"
+    )
+    self.tic()
+
+    event_relative_url = self.support_request.REQUEST.get("event_relative_url")
+    event = self.portal.restrictedTraverse(event_relative_url)
+
+    self.assertEqual(event.getSimulationState(), "stopped")
+    self.assertEqual(self.support_request.getSimulationState(),
+      'validated')
+    self.assertEqual(self.support_request.getDestinationDecision(),
+      event.getSource())
+    self.assertEqual(person, event.getSourceValue())
+
+    self.assertEqual(self.support_request.getResource(),
+      event.getResource())
+    self.assertEqual(self.support_request,
+      event.getFollowUpValue())
+    
+    self.assertEqual(event.getTitle(), "A")
+    self.assertEqual(event.getTextContent(), "B")
+    self.assertEqual(event.getContentType(), "text/plain")
+    self.assertEqual(event.getPortalType(), "Web Message")
+    self.assertEqual(event.getDestination(),
+      self.support_request.getSource())
+
+  def test_SupportRequest_notify_noParameter(self):
+    self.assertRaises(TypeError, self.support_request.notify)
+    self.assertRaises(TypeError, self.support_request.notify, message_title="A")
+    self.assertRaises(TypeError, self.support_request.notify, message="A")
+    self.assertRaises(TypeError, self.support_request.notify, destination_relative_url="A")
+
+  def test_SupportRequest_notify(self):
+    person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
+
+    self.support_request.approveRegistration()
+    self.tic()
+
+    self.logout()
+    self.login()
+
+    self.support_request.notify(
+      message_title="A",
+      message="B")
+
+    event = self.support_request.REQUEST.get("ticket_notified_item")
+
+    self.assertEqual(event.getSimulationState(), "delivered")
+    self.assertEqual(self.support_request.getSimulationState(),
+      'validated')
+    
+    self.assertEqual(self.support_request.getDestinationDecision(),
+      event.getDestination())
+    self.assertEqual(person, event.getDestinationValue())
+
+    self.assertEqual("service_module/slapos_crm_information",
+      event.getResource())
+    self.assertEqual(self.support_request,
+      event.getFollowUpValue())
+    
+    self.assertEqual(event.getTitle(), "A")
+    self.assertEqual(event.getTextContent(), "B")
+    self.assertEqual(event.getContentType(), "text/html")
+    self.assertEqual(event.getPortalType(), "Web Message")
+    self.assertEqual(event.getSource(),
+      self.support_request.getSource())
+
+    # Retry now to see if doesn't create a new message
+    self.support_request.notify(
+      message_title="A",
+      message="B")
+    self.tic()
+
+    self.assertEqual(event,
+      self.support_request.REQUEST.get("ticket_notified_item"))
+
+    # Retry, now it must create a new one
+    self.support_request.notify(
+      message_title="C",
+      message="B")
+    self.tic()
+
+    self.assertNotEqual(event,
+      self.support_request.REQUEST.get("ticket_notified_item"))
+
+    # Remove completly the ticket_notified_item and try to create a new one
+    # It should find it anyway from catalog.
+    self.support_request.REQUEST.set("ticket_notified_item", None)
+    self.commit()
+    
+    # Retry, now it must create a new one
+    self.support_request.notify(
+      message_title="A",
+      message="B")
+    self.tic()
+
+    self.assertEqual(event,
+      self.support_request.REQUEST.get("ticket_notified_item"))
+
+
+
diff --git a/master/bt5/slapos_crm/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudTicketSlapInterfaceWorkflow.xml b/master/bt5/slapos_crm/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudTicketSlapInterfaceWorkflow.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7ad833f122330c8f75158349c35cfb2313a8cc57
--- /dev/null
+++ b/master/bt5/slapos_crm/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudTicketSlapInterfaceWorkflow.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Test Component" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_recorded_property_dict</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>default_reference</string> </key>
+            <value> <string>testSlapOSCloudTicketSlapInterfaceWorkflow</string> </value>
+        </item>
+        <item>
+            <key> <string>default_source_reference</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>test.erp5.testSlapOSCloudTicketSlapInterfaceWorkflow</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Test Component</string> </value>
+        </item>
+        <item>
+            <key> <string>sid</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>text_content_error_message</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>text_content_warning_message</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>version</string> </key>
+            <value> <string>erp5</string> </value>
+        </item>
+        <item>
+            <key> <string>workflow_history</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>component_validation_workflow</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+                    </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="4" aka="AAAAAAAAAAQ=">
+    <pickle>
+      <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_log</string> </key>
+            <value>
+              <list>
+                <dictionary>
+                  <item>
+                      <key> <string>action</string> </key>
+                      <value> <string>validate</string> </value>
+                  </item>
+                  <item>
+                      <key> <string>validation_state</string> </key>
+                      <value> <string>validated</string> </value>
+                  </item>
+                </dictionary>
+              </list>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow.xml
new file mode 100644
index 0000000000000000000000000000000000000000..37bc46cbde3b8b4f363b7f194397d52c085e2014
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_count</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>_mt_index</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>_tree</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>source/portal_workflow/ticket_slap_interface_workflow/state_draft</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>comment</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>default_reference</string> </key>
+            <value> <string>person_slap_interface_workflow</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>ticket_slap_interface_workflow</string> </value>
+        </item>
+        <item>
+            <key> <string>language</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>manager_bypass</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow</string> </value>
+        </item>
+        <item>
+            <key> <string>state_variable</string> </key>
+            <value> <string>slap_state</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Ticket Slap Interface Workflow</string> </value>
+        </item>
+        <item>
+            <key> <string>workflow_managed_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="Length" module="BTrees.Length"/>
+    </pickle>
+    <pickle> <int>0</int> </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="OOBTree" module="BTrees.OOBTree"/>
+    </pickle>
+    <pickle>
+      <none/>
+    </pickle>
+  </record>
+  <record id="4" aka="AAAAAAAAAAQ=">
+    <pickle>
+      <global name="OOBTree" module="BTrees.OOBTree"/>
+    </pickle>
+    <pickle>
+      <none/>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_approveRegistration.py b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_approveRegistration.py
new file mode 100644
index 0000000000000000000000000000000000000000..f0133c3d0bcd3b885ac3ba00fcb9d353f3ece577
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_approveRegistration.py
@@ -0,0 +1,43 @@
+ticket = state_change["object"]
+from DateTime import DateTime
+
+portal = context.getPortalObject()
+
+if ticket.getSimulationState() != "draft":
+  return
+
+if ticket.getReference() in [None, ""]:
+  raise ValueError("Reference is missing on the Ticket")
+
+# Get the user id of the context owner.
+local_role_list = ticket.get_local_roles()
+for group, role_list in local_role_list:
+  if 'Owner' in role_list:
+    user_id = group
+    break
+
+person = portal.portal_catalog.getResultValue(user_id=user_id)
+if person is None:
+  # Value was created by super user, so there isn't a point on continue
+  return
+
+# XXX unhardcode the trade condition, by adding a preference
+if ticket.getSpecialise() != "sale_trade_condition_module/slapos_ticket_trade_condition":
+  return
+
+trade_condition = portal.sale_trade_condition_module.slapos_ticket_trade_condition
+
+ticket.edit(
+  source_section=trade_condition.getSourceSection(),
+  source_trade=trade_condition.getSourceSection(),
+  source=trade_condition.getSource())
+
+ticket.setStartDate(DateTime())
+
+ticket.requestEvent(
+  event_title=ticket.getTitle(),
+  event_content=ticket.getDescription()
+)
+
+event_relative_url = context.REQUEST.get("event_relative_url")
+ticket.setCausality(event_relative_url)
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_approveRegistration.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_approveRegistration.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c0e92fe7548a3a216be14d930b736f8e8977ec3c
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_approveRegistration.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Script" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>state_change</string> </value>
+        </item>
+        <item>
+            <key> <string>_proxy_roles</string> </key>
+            <value>
+              <tuple>
+                <string>Assignor</string>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>script_Ticket_approveRegistration</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Script</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Ticket_approveRegistration</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_checkConsistency.py b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_checkConsistency.py
new file mode 100644
index 0000000000000000000000000000000000000000..9687ff0729284eccfa4c877aa13b09add3666d58
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_checkConsistency.py
@@ -0,0 +1,2 @@
+ticket = state_change['object']
+ticket.Base_checkConsistency()
diff --git a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_Ticket_createInitialEvent.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_checkConsistency.xml
similarity index 94%
rename from master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_Ticket_createInitialEvent.xml
rename to master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_checkConsistency.xml
index 27f64b2de51399b210b32c3fbc9d4f34f80d6530..cbb5b3a7322486242560ea4ce01390f267a07bc3 100644
--- a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_Ticket_createInitialEvent.xml
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_checkConsistency.xml
@@ -50,7 +50,7 @@
         </item>
         <item>
             <key> <string>_params</string> </key>
-            <value> <string>state_object</string> </value>
+            <value> <string>state_change</string> </value>
         </item>
         <item>
             <key> <string>description</string> </key>
@@ -60,7 +60,7 @@
         </item>
         <item>
             <key> <string>id</string> </key>
-            <value> <string>script_Ticket_createInitialEvent</string> </value>
+            <value> <string>script_Ticket_checkConsistency</string> </value>
         </item>
         <item>
             <key> <string>portal_type</string> </key>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_notify.py b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_notify.py
new file mode 100644
index 0000000000000000000000000000000000000000..36fc4f5c75542f6b774aa556caf1fe9e76ac7137
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_notify.py
@@ -0,0 +1,54 @@
+ticket = state_change["object"]
+from DateTime import DateTime
+portal = ticket.getPortalObject()
+
+# Get required arguments
+kwargs = state_change.kwargs
+
+# Required args
+# Raise TypeError if all parameters are not provided
+try:
+  message_title = kwargs['message_title']
+  message = kwargs['message']
+except KeyError:
+  raise TypeError("Ticket_notify takes exactly 2 arguments")
+
+resource = portal.service_module.slapos_crm_information.getRelativeUrl()
+
+# create Web message if needed for this ticket
+last_event = ticket.portal_catalog.getResultValue(
+             title=message_title,
+             follow_up_uid=ticket.getUid(),
+             sort_on=[('delivery.start_date', 'DESC')],
+)
+if last_event:
+  # User has already been notified for this problem.
+  ticket.REQUEST.set("ticket_notified_item", last_event)
+  return
+
+transactional_event = ticket.REQUEST.get("ticket_notified_item", None)
+
+if transactional_event is not None:
+  if (transactional_event.getFollowUpUid() == ticket.getUid()) and \
+    (transactional_event.getTitle() == message_title):
+    ticket.REQUEST.set("ticket_notified_item", transactional_event)
+    return
+
+template = portal.restrictedTraverse(
+        portal.portal_preferences.getPreferredWebMessageTemplate())
+
+event = template.Base_createCloneDocument(batch_mode=1)
+event.edit(
+  title=message_title,
+  text_content=message,
+  start_date = DateTime(),
+  resource = resource,
+  source=ticket.getSource(),
+  destination=ticket.getDestinationDecision(),
+  follow_up=ticket.getRelativeUrl(),
+)
+event.stop()
+event.deliver()
+
+ticket.serialize()
+ticket.REQUEST.set("ticket_notified_item", event)
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_notify.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_notify.xml
new file mode 100644
index 0000000000000000000000000000000000000000..accc3738ae218c21bd56687d1dcd5e1644619f56
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_notify.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Script" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>state_change</string> </value>
+        </item>
+        <item>
+            <key> <string>_proxy_roles</string> </key>
+            <value>
+              <tuple>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>script_Ticket_notify</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Script</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Ticket_notify</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_requestEvent.py b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_requestEvent.py
new file mode 100644
index 0000000000000000000000000000000000000000..03a851c69170002e520c9493829ae879571f8aed
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_requestEvent.py
@@ -0,0 +1,30 @@
+ticket = state_change["object"]
+from DateTime import DateTime
+portal = context.getPortalObject()
+# Get required arguments
+kwargs = state_change.kwargs
+
+# Required args
+# Raise TypeError if all parameters are not provided
+try:
+  title = kwargs['event_title']
+  text_content = kwargs['event_content']
+except KeyError:
+  raise TypeError, "Ticket_requestEvent takes exactly 2 argument"
+
+web_message = portal.event_module.newContent(
+  portal_type="Web Message",
+  title=title,
+  text_content=text_content,
+  source=ticket.getDestinationDecision(),
+  content_type="text/plain",
+  destination=ticket.getSource(),
+  resource=ticket.getResource(),
+  follow_up=ticket.getRelativeUrl()
+)
+
+web_message.stop(comment="Submitted from the renderjs app")
+if portal.portal_workflow.isTransitionPossible(ticket, "validate"):
+  ticket.validate(comment="See %s" % web_message.getRelativeUrl())
+
+ticket.REQUEST.set("event_relative_url", web_message.getRelativeUrl())
diff --git a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_SupportRequest_createInitialWebMessage.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_requestEvent.xml
similarity index 91%
rename from master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_SupportRequest_createInitialWebMessage.xml
rename to master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_requestEvent.xml
index 84628e68ba5ee367ef9454c9bc8e12066e3dbeec..97c83b569fe935ef8772784ce147fdaddd9abad8 100644
--- a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_SupportRequest_createInitialWebMessage.xml
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/script_Ticket_requestEvent.xml
@@ -50,13 +50,14 @@
         </item>
         <item>
             <key> <string>_params</string> </key>
-            <value> <string>state_object</string> </value>
+            <value> <string>state_change</string> </value>
         </item>
         <item>
             <key> <string>_proxy_roles</string> </key>
             <value>
               <tuple>
                 <string>Assignor</string>
+                <string>Owner</string>
               </tuple>
             </value>
         </item>
@@ -68,7 +69,7 @@
         </item>
         <item>
             <key> <string>id</string> </key>
-            <value> <string>script_SupportRequest_createInitialWebMessage</string> </value>
+            <value> <string>script_Ticket_requestEvent</string> </value>
         </item>
         <item>
             <key> <string>portal_type</string> </key>
@@ -76,9 +77,7 @@
         </item>
         <item>
             <key> <string>title</string> </key>
-            <value>
-              <none/>
-            </value>
+            <value> <string>Ticket_requestEvent</string> </value>
         </item>
       </dictionary>
     </pickle>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/state_draft.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/state_draft.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3dae19866338152c4358819be906e10dbeba8b0c
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/state_draft.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow State" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>acquire_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>destination/portal_workflow/ticket_slap_interface_workflow/transition_approve_registration</string>
+                <string>destination/portal_workflow/ticket_slap_interface_workflow/transition_notify</string>
+                <string>destination/portal_workflow/ticket_slap_interface_workflow/transition_request_event</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>comment</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>state_draft</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow State</string> </value>
+        </item>
+        <item>
+            <key> <string>state_permission_role_list_dict</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>state_type</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Draft</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/transition_approve_registration.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/transition_approve_registration.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3aef7a3be5eb48756e6c0183e93344c0e00ade81
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/transition_approve_registration.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Transition" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>action</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>action_name</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>action_type/workflow</string>
+                <string>before_script/portal_workflow/ticket_slap_interface_workflow/script_Ticket_checkConsistency</string>
+                <string>after_script/portal_workflow/ticket_slap_interface_workflow/script_Ticket_approveRegistration</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>guard_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>icon</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>transition_approve_registration</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Transition</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Approve Registration</string> </value>
+        </item>
+        <item>
+            <key> <string>trigger_type</string> </key>
+            <value> <int>2</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/transition_notify.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/transition_notify.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fe69b3928252a6801b3e3ac7f2501c3fdc8b4277
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/transition_notify.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Transition" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>action</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>action_name</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>action_type/workflow</string>
+                <string>before_script/portal_workflow/ticket_slap_interface_workflow/script_Ticket_checkConsistency</string>
+                <string>after_script/portal_workflow/ticket_slap_interface_workflow/script_Ticket_notify</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>guard_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>icon</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>transition_notify</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Transition</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Notify</string> </value>
+        </item>
+        <item>
+            <key> <string>trigger_type</string> </key>
+            <value> <int>2</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/transition_request_event.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/transition_request_event.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c2461cd29db2461907ae70f9df52c47b6815066e
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/transition_request_event.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Transition" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>action</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>action_name</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>action_type/workflow</string>
+                <string>before_script/portal_workflow/ticket_slap_interface_workflow/script_Ticket_checkConsistency</string>
+                <string>after_script/portal_workflow/ticket_slap_interface_workflow/script_Ticket_requestEvent</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>guard_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>icon</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>transition_request_event</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Transition</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Request Event</string> </value>
+        </item>
+        <item>
+            <key> <string>trigger_type</string> </key>
+            <value> <int>2</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_action.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_action.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba0016f3d69b0273369ad6802eb18c8313ea614e
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_action.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>The last transition</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_action</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>variable_default_expression</string> </key>
+            <value> <string>transition/getReference|nothing</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_actor.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_actor.xml
new file mode 100644
index 0000000000000000000000000000000000000000..028d9db6a333f0cda3309140372c927214decf31
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_actor.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>The name of the user who performed the last transition</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_actor</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>variable_default_expression</string> </key>
+            <value> <string>user/getUserName</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_comment.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_comment.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b41853beaf1d6aea72c0e4eb3cbdcaa4969ebfc8
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_comment.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Comments about the last transition</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_comment</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>variable_default_expression</string> </key>
+            <value> <string>python:state_change.kwargs.get(\'comment\', \'\')</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_error_message.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_error_message.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2b761c20e6aaa4fc8708edf2ce7109154b8427d5
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_error_message.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Error message if validation failed</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_error_message</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_history.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_history.xml
new file mode 100644
index 0000000000000000000000000000000000000000..95a08300b717c82a90e3a2906285f051479b38a2
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_history.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Provides access to workflow history</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_history</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>variable_default_expression</string> </key>
+            <value> <string>state_change/getHistory</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_portal_type.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_portal_type.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3609f65ad5051b7649d2b055bca6dd2d0fd70551
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_portal_type.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>portal type (use as filter for worklists)</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_portal_type</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_time.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_time.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4e488bde05a81a4b25e955b22ea25ba4e6c56d9c
--- /dev/null
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_slap_interface_workflow/variable_time.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Time of the last transition</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_time</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>variable_default_expression</string> </key>
+            <value> <string>state_change/getDateTime</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_workflow.xml b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_workflow.xml
index 8f704f6eb66a68d46e5797ae5b96a447121936d8..f52d62131d7eae943bbca240fd3adbc278ec8046 100644
--- a/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_workflow.xml
+++ b/master/bt5/slapos_crm/WorkflowTemplateItem/portal_workflow/ticket_workflow.xml
@@ -32,6 +32,12 @@
               </tuple>
             </value>
         </item>
+        <item>
+            <key> <string>comment</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
         <item>
             <key> <string>default_reference</string> </key>
             <value> <string>ticket_workflow</string> </value>
diff --git a/master/bt5/slapos_crm/bt/template_portal_type_workflow_chain_list b/master/bt5/slapos_crm/bt/template_portal_type_workflow_chain_list
index 1a98d85d893d342cc80c09a4d323eb1de43050a1..8a7e562332dd8351cea701baf11c178de37e3017 100644
--- a/master/bt5/slapos_crm/bt/template_portal_type_workflow_chain_list
+++ b/master/bt5/slapos_crm/bt/template_portal_type_workflow_chain_list
@@ -3,4 +3,5 @@ Incident Response | ticket_workflow
 Regularisation Request | edit_workflow
 Regularisation Request | pricing_interaction_workflow
 Regularisation Request | ticket_interaction_workflow
-Regularisation Request | ticket_workflow
\ No newline at end of file
+Regularisation Request | ticket_workflow
+Support Request | ticket_slap_interface_workflow
\ No newline at end of file
diff --git a/master/bt5/slapos_crm/bt/template_test_id_list b/master/bt5/slapos_crm/bt/template_test_id_list
index df561755f6326ac62b2e81b8f55c1b2af3242fde..d6db53b15808e50d870e829d053b6b728e345064 100644
--- a/master/bt5/slapos_crm/bt/template_test_id_list
+++ b/master/bt5/slapos_crm/bt/template_test_id_list
@@ -1,3 +1,4 @@
 test.erp5.testSlapOSCRMSkins
 test.erp5.testSlapOSCRMRegularisationRequestSkins
-test.erp5.testSlapOSCRMAlarm
\ No newline at end of file
+test.erp5.testSlapOSCRMAlarm
+test.erp5.testSlapOSCloudTicketSlapInterfaceWorkflow
\ No newline at end of file
diff --git a/master/bt5/slapos_crm/bt/template_workflow_id_list b/master/bt5/slapos_crm/bt/template_workflow_id_list
index 4b3b1db595479f0bad108c71e14e8fa16fc4eec8..c356d787f5d4df3af90a687ddd00d3e016d56b92 100644
--- a/master/bt5/slapos_crm/bt/template_workflow_id_list
+++ b/master/bt5/slapos_crm/bt/template_workflow_id_list
@@ -1 +1,2 @@
+ticket_slap_interface_workflow
 ticket_workflow
\ No newline at end of file
diff --git a/master/bt5/slapos_erp5/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml b/master/bt5/slapos_erp5/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
index 882d797ebc1dc9c84b66087a8a3d28303af549e2..06b405589d293e37a692b8b3f5978cc55c55e0ff 100644
--- a/master/bt5/slapos_erp5/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
+++ b/master/bt5/slapos_erp5/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
@@ -123,14 +123,6 @@
   <type>Software Instance</type>
   <workflow>local_permission_slapos_interaction_workflow</workflow>
  </chain>
- <chain>
-  <type>Support Request</type>
-  <workflow>slapos_erp5_interaction_workflow</workflow>
- </chain>
- <chain>
-  <type>Web Message</type>
-  <workflow>slapos_erp5_interaction_workflow</workflow>
- </chain>
  <chain>
   <type>Wechat Event</type>
   <workflow>local_permission_slapos_interaction_workflow</workflow>
diff --git a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_SupportRequest_createInitialWebMessage.py b/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_SupportRequest_createInitialWebMessage.py
deleted file mode 100644
index 069bd0eec7d714f77bb9ab45f4ddefa83daca6ac..0000000000000000000000000000000000000000
--- a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_SupportRequest_createInitialWebMessage.py
+++ /dev/null
@@ -1,37 +0,0 @@
-ticket = state_object["object"]
-
-from DateTime import DateTime
-portal = context.getPortalObject()
-
-# XXX unhardcode the trade condition, by adding a preference
-if ticket.getSpecialise() != "sale_trade_condition_module/slapos_ticket_trade_condition":
-  return
-
-if ticket.getSimulationState() != "draft":
-  return
-
-ticket.validate()
-
-trade_condition = portal.sale_trade_condition_module.slapos_ticket_trade_condition
-
-web_message = context.Ticket_createInitialEvent(state_object)
-
-ticket.edit(
-  source_section = trade_condition.getSourceSection(),
-  source_trade=trade_condition.getSourceSection(),
-  source=trade_condition.getSource(),
-  causality_value=web_message)
-
-ticket.setStartDate(DateTime())
-
-# Copy original post into the original message.
-web_message.edit(
-  title=ticket.getTitle(),
-#  content_type="text/plain",
-  text_content=ticket.getDescription(),
-  source=ticket.getDestinationDecision(),
-#  destination=trade_condition.getSource(),
-#  resource=ticket.getResource(),
-#  start_date=DateTime(),
-  follow_up_value=ticket,
-)
diff --git a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_Ticket_createInitialEvent.py b/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_Ticket_createInitialEvent.py
deleted file mode 100644
index c1fbcc794a69ce3ae47bc9e8ff676ba4006ef213..0000000000000000000000000000000000000000
--- a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_Ticket_createInitialEvent.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Added this script to be running as Owner
-portal = context.getPortalObject()
-
-return portal.event_module.newContent(
-  portal_type="Web Message",
-)
diff --git a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_WebMessage_stopAndReopenTicket.py b/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_WebMessage_stopAndReopenTicket.py
deleted file mode 100644
index b0ef83c296a3b7855d8d388f7748c68c4a2e4b83..0000000000000000000000000000000000000000
--- a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_WebMessage_stopAndReopenTicket.py
+++ /dev/null
@@ -1,38 +0,0 @@
-web_message = state_object["object"]
-portal = context.getPortalObject()
-person = portal.portal_membership.getAuthenticatedMember().getUserValue()
-
-if person is None:
-  return
-
-if web_message.getSimulationState() != "draft":
-  return
-
-if not web_message.hasStartDate():
-  web_message.setStartDate(DateTime())
-
-# The user isn't the customer, so it is not comming from the user
-# interface.
-ticket = web_message.getFollowUpValue()
-if ticket.getDestinationDecision() != person.getRelativeUrl():
-  return
-
-# The user isn't the sender, so it is not comming from UI, but from
-# an alarm.
-source = web_message.getSource()
-if source != person.getRelativeUrl():
-  return
-
-edit_kw = {"content_type":"text/plain"}
-# Copy destination and resource from ticket.
-if web_message.getDestination() is None:
-  edit_kw["destination"] = ticket.getSource()
-
-if web_message.getResource() is None:
-  edit_kw["resource"] = ticket.getResource()
-
-web_message.edit(**edit_kw)
-
-web_message.stop(comment="Submitted from the renderjs app")
-if portal.portal_workflow.isTransitionPossible(ticket, "validate"):
-  ticket.validate(comment="See %s" % web_message.getRelativeUrl())
diff --git a/master/bt5/slapos_erp5/bt/template_portal_type_workflow_chain_list b/master/bt5/slapos_erp5/bt/template_portal_type_workflow_chain_list
index 7af62f0d678d993b1b71ff8b35dc8b5d62a6cfc4..b90a515b87b127e5456ede198ac1abf26443b815 100644
--- a/master/bt5/slapos_erp5/bt/template_portal_type_workflow_chain_list
+++ b/master/bt5/slapos_erp5/bt/template_portal_type_workflow_chain_list
@@ -34,6 +34,4 @@ Sale Packing List | local_permission_slapos_interaction_workflow
 Slave Instance | local_permission_slapos_interaction_workflow
 Software Installation | local_permission_slapos_interaction_workflow
 Software Instance | local_permission_slapos_interaction_workflow
-Support Request | slapos_erp5_interaction_workflow
-Web Message | slapos_erp5_interaction_workflow
 Wechat Event | local_permission_slapos_interaction_workflow
\ No newline at end of file
diff --git a/master/bt5/slapos_jio/PathTemplateItem/web_page_module/rjs_gadget_erp5_page_slap_add_ticket_js.js b/master/bt5/slapos_jio/PathTemplateItem/web_page_module/rjs_gadget_erp5_page_slap_add_ticket_js.js
index b8b1cd06b7b9262165d98a8e492fe2c835a55e5d..f170d09540583998432dbb66c1929b511f8aabe3 100644
--- a/master/bt5/slapos_jio/PathTemplateItem/web_page_module/rjs_gadget_erp5_page_slap_add_ticket_js.js
+++ b/master/bt5/slapos_jio/PathTemplateItem/web_page_module/rjs_gadget_erp5_page_slap_add_ticket_js.js
@@ -11,9 +11,10 @@
     .declareAcquiredMethod("updatePanel", "updatePanel")
     .declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
     .declareAcquiredMethod("getSetting", "getSetting")
+    .declareAcquiredMethod("getSettingList", "getSettingList")
     .declareAcquiredMethod("getUrlFor", "getUrlFor")
     .declareAcquiredMethod("redirect", "redirect")
-    .declareAcquiredMethod("jio_post", "jio_post")
+    .declareAcquiredMethod("jio_putAttachment", "jio_putAttachment")
     .declareAcquiredMethod("jio_get", "jio_get")
     .declareAcquiredMethod("notifySubmitting", "notifySubmitting")
     .declareAcquiredMethod("notifySubmitted", 'notifySubmitted')
@@ -26,6 +27,7 @@
       return this.triggerSubmit();
     })
 
+
     .onEvent('submit', function () {
       var gadget = this;
       return gadget.notifySubmitting()
@@ -33,28 +35,31 @@
           return gadget.getDeclaredGadget('form_view');
         })
         .push(function (form_gadget) {
-          return form_gadget.getContent();
+          return RSVP.all([form_gadget.getContent(),
+                          gadget.getSettingList(['me', 'hateoas_url'])]);
         })
-        .push(function (content) {
-          var property, doc = {};
-          for (property in content) {
-            if ((content.hasOwnProperty(property)) &&
-                // Remove undefined keys added by Gadget fields
-                (property !== "undefined") &&
-                // Remove default_*:int keys added by ListField
-                !(property.endsWith(":int") && property.startsWith("default_"))) {
-              doc[property] = content[property];
-            }
-
-          }
-          return gadget.jio_post(doc);
+        .push(function (result) {
+          var doc = result[0],
+            me = result[1][0],
+            url = result[1][1];
+          return gadget.jio_putAttachment(me,
+                url + me + "/Person_requestSupport",
+                {title: doc.title,
+                 description: doc.description,
+                 resource: doc.resource});
         })
-        .push(function (key) {
+        .push(function (attachment) {
+          return jIO.util.readBlobAsText(attachment.target.response);
+        })
+        .push(function (response) {
+          return JSON.parse(response.target.result);
+        })
+        .push(function (result) {
           return gadget.notifySubmitted({message: gadget.message_translation, status: 'success'})
             .push(function () {
               // Workaround, find a way to open document without break gadget.
               return gadget.redirect({"command": "change",
-                                    "options": {"jio_key": key, "page": "slap_controller"}});
+                                    "options": {"jio_key": result.relative_url, "page": "slap_controller"}});
             });
         });
     })
@@ -88,20 +93,19 @@
             gadget.getDeclaredGadget('form_view'),
             gadget.jio_getAttachment("ticket_resource_list",
                hateoas_url + "Ticket_getResourceItemListAsJSON"),
-            window.getSettingMe(gadget),
             gadget.getTranslationList(translation_list)
 
           ]);
         })
         .push(function (result) {
-          gadget.message_translation = result[3][0];
-          page_title_translation = result[3][10];
+          gadget.message_translation = result[2][0];
+          page_title_translation = result[2][10];
           return result[0].render({
             erp5_document: {
               "_embedded": {"_view": {
                 "my_title": {
-                  "description": result[3][1],
-                  "title": result[3][2],
+                  "description": result[2][1],
+                  "title": result[2][2],
                   "default": "",
                   "css_class": "",
                   "required": 1,
@@ -112,7 +116,7 @@
                 },
                 "my_description": {
                   "description": "",
-                  "title": result[3][3],
+                  "title": result[2][3],
                   "default": "",
                   "css_class": "",
                   "required": 1,
@@ -122,8 +126,8 @@
                   "type": "TextAreaField"
                 },
                 "my_resource": {
-                  "description": result[3][0],
-                  "title": result[3][4],
+                  "description": result[2][0],
+                  "title": result[2][4],
                   "default": "",
                   "items": result[1],
                   "css_class": "",
@@ -132,52 +136,6 @@
                   "key": "resource",
                   "hidden": 0,
                   "type": "ListField"
-                },
-                "my_destination_decision": {
-                  "description": result[3][0],
-                  "title": result[3][5],
-                  "default": result[2],
-                  "css_class": "",
-                  "required": 1,
-                  "editable": 1,
-                  "key": "destination_decision",
-                  "hidden": 1,
-                  "type": "StringField"
-                },
-                "my_specialise": {
-                  "description": "",
-                  "title": result[3][6],
-                  // Auto Set a hardcoded trade Condition
-                  // Please replace it by a getSetting.
-                  "default": "sale_trade_condition_module/slapos_ticket_trade_condition",
-                  "css_class": "",
-                  "required": 1,
-                  "editable": 1,
-                  "key": "specialise",
-                  "hidden": 1,
-                  "type": "StringField"
-                },
-                "my_portal_type": {
-                  "description": result[3][0],
-                  "title": result[3][7],
-                  "default": "Support Request",
-                  "css_class": "",
-                  "required": 1,
-                  "editable": 1,
-                  "key": "portal_type",
-                  "hidden": 1,
-                  "type": "StringField"
-                },
-                "my_parent_relative_url": {
-                  "description": "",
-                  "title": result[3][9],
-                  "default": "support_request_module",
-                  "css_class": "",
-                  "required": 1,
-                  "editable": 1,
-                  "key": "parent_relative_url",
-                  "hidden": 1,
-                  "type": "StringField"
                 }
               }},
               "_links": {
@@ -193,7 +151,7 @@
                 [["my_resource"]]
               ], [
                 "center",
-                [["my_title"], ["my_description"], ["my_specialise"], ["my_destination_decision"], ["my_portal_type"], ["my_parent_relative_url"]]
+                [["my_title"], ["my_description"]]
               ]]
             }
           });
diff --git a/master/bt5/slapos_jio/PathTemplateItem/web_page_module/rjs_gadget_erp5_page_slap_add_ticket_js.xml b/master/bt5/slapos_jio/PathTemplateItem/web_page_module/rjs_gadget_erp5_page_slap_add_ticket_js.xml
index 6320fc037256107251dbef1eb6998ed72ecca968..da67a88e1a3b5593008d59a9a737d26d93a95c4c 100644
--- a/master/bt5/slapos_jio/PathTemplateItem/web_page_module/rjs_gadget_erp5_page_slap_add_ticket_js.xml
+++ b/master/bt5/slapos_jio/PathTemplateItem/web_page_module/rjs_gadget_erp5_page_slap_add_ticket_js.xml
@@ -279,7 +279,7 @@
                   </item>
                   <item>
                       <key> <string>serial</string> </key>
-                      <value> <string>987.11835.35244.22135</string> </value>
+                      <value> <string>997.18055.28455.10120</string> </value>
                   </item>
                   <item>
                       <key> <string>state</string> </key>
@@ -297,7 +297,7 @@
                           </tuple>
                           <state>
                             <tuple>
-                              <float>1602260862.83</float>
+                              <float>1641264462.37</float>
                               <string>UTC</string>
                             </tuple>
                           </state>
diff --git a/master/bt5/slapos_jio/SkinTemplateItem/portal_skins/slapos_hal_json_style/Person_requestSupport.py b/master/bt5/slapos_jio/SkinTemplateItem/portal_skins/slapos_hal_json_style/Person_requestSupport.py
new file mode 100644
index 0000000000000000000000000000000000000000..302588ea31a3e7da03bfbbc7c84f973bfaf93436
--- /dev/null
+++ b/master/bt5/slapos_jio/SkinTemplateItem/portal_skins/slapos_hal_json_style/Person_requestSupport.py
@@ -0,0 +1,21 @@
+import json
+portal = context.getPortalObject()
+person = portal.portal_membership.getAuthenticatedMember().getUserValue()
+
+request = context.REQUEST
+response = request.RESPONSE
+
+if person is None:
+  response.setStatus(403)
+else:
+  request_kw = {"support_request_title": title,
+                "support_request_description": description,
+                "support_request_resource": resource,
+                "support_request_aggregate": aggregate}
+  person.requestSupport(**request_kw)
+  support_relative_url = request.get('support_request_relative_url')
+
+  response.setHeader('Content-Type', "application/json")
+  return json.dumps({
+    "relative_url": support_relative_url
+  })
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getComputeNode.xml b/master/bt5/slapos_jio/SkinTemplateItem/portal_skins/slapos_hal_json_style/Person_requestSupport.xml
similarity index 93%
rename from master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getComputeNode.xml
rename to master/bt5/slapos_jio/SkinTemplateItem/portal_skins/slapos_hal_json_style/Person_requestSupport.xml
index 1f1f8e83e336df91ca8bdf8ca4f1d3b691a32262..064dc43f2f3b39ff33552ed93928c5e9b4d2d175 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getComputeNode.xml
+++ b/master/bt5/slapos_jio/SkinTemplateItem/portal_skins/slapos_hal_json_style/Person_requestSupport.xml
@@ -50,11 +50,11 @@
         </item>
         <item>
             <key> <string>_params</string> </key>
-            <value> <string></string> </value>
+            <value> <string>title, description, resource, aggregate=None</string> </value>
         </item>
         <item>
             <key> <string>id</string> </key>
-            <value> <string>UpgradeDecision_getComputeNode</string> </value>
+            <value> <string>Person_requestSupport</string> </value>
         </item>
       </dictionary>
     </pickle>
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getInstanceTree.xml b/master/bt5/slapos_jio_ui_test/PathTemplateItem/portal_tests/slaposjs_zuite/testSlapOSJSServerTicketRelated.xml
similarity index 56%
rename from master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getInstanceTree.xml
rename to master/bt5/slapos_jio_ui_test/PathTemplateItem/portal_tests/slaposjs_zuite/testSlapOSJSServerTicketRelated.xml
index 6165fd3d9311ad12c6a866167584165dc83ba620..3fed2ae5b0f87d0387a159990dc534b31ecffe99 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getInstanceTree.xml
+++ b/master/bt5/slapos_jio_ui_test/PathTemplateItem/portal_tests/slaposjs_zuite/testSlapOSJSServerTicketRelated.xml
@@ -2,14 +2,10 @@
 <ZopeData>
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
-      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+      <global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
     </pickle>
     <pickle>
       <dictionary>
-        <item>
-            <key> <string>Script_magic</string> </key>
-            <value> <int>3</int> </value>
-        </item>
         <item>
             <key> <string>_bind_names</string> </key>
             <value>
@@ -24,18 +20,6 @@
                         <key> <string>_asgns</string> </key>
                         <value>
                           <dictionary>
-                            <item>
-                                <key> <string>name_container</string> </key>
-                                <value> <string>container</string> </value>
-                            </item>
-                            <item>
-                                <key> <string>name_context</string> </key>
-                                <value> <string>context</string> </value>
-                            </item>
-                            <item>
-                                <key> <string>name_m_self</string> </key>
-                                <value> <string>script</string> </value>
-                            </item>
                             <item>
                                 <key> <string>name_subpath</string> </key>
                                 <value> <string>traverse_subpath</string> </value>
@@ -49,12 +33,24 @@
             </value>
         </item>
         <item>
-            <key> <string>_params</string> </key>
-            <value> <string></string> </value>
+            <key> <string>content_type</string> </key>
+            <value> <string>text/html</string> </value>
+        </item>
+        <item>
+            <key> <string>expand</string> </key>
+            <value> <int>0</int> </value>
         </item>
         <item>
             <key> <string>id</string> </key>
-            <value> <string>UpgradeDecision_getInstanceTree</string> </value>
+            <value> <string>testSlapOSJSServerTicketRelated</string> </value>
+        </item>
+        <item>
+            <key> <string>output_encoding</string> </key>
+            <value> <string>utf-8</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <unicode></unicode> </value>
         </item>
       </dictionary>
     </pickle>
diff --git a/master/bt5/slapos_jio_ui_test/PathTemplateItem/portal_tests/slaposjs_zuite/testSlapOSJSServerTicketRelated.zpt b/master/bt5/slapos_jio_ui_test/PathTemplateItem/portal_tests/slaposjs_zuite/testSlapOSJSServerTicketRelated.zpt
new file mode 100644
index 0000000000000000000000000000000000000000..7849a4d9f54cf85b9dbd3e9aeb502bc7978b65ac
--- /dev/null
+++ b/master/bt5/slapos_jio_ui_test/PathTemplateItem/portal_tests/slaposjs_zuite/testSlapOSJSServerTicketRelated.zpt
@@ -0,0 +1,381 @@
+<html xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal">
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+  <title>Test SlapOS JS Server</title>
+</head>
+
+<body>
+  <table cellpadding="1" cellspacing="1" border="1">
+    <thead>
+      <tr>
+        <td rowspan="1" colspan="3">Test SlapOS JS Server Add related Ticket</td>
+      </tr>
+    </thead>
+    <tbody>
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_init" />
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/set_default_available_language"/>
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_login" />
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
+
+      <tal:block define="document_title python: 'TEST-SLAPOSJS-COMPUTER 0';">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/create_simple_compute_node" />
+      </tal:block>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
+
+
+      <tal:block define="menu_item python: 'Servers'; header menu_item">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>click</td>
+        <td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
+        <td></td>
+      </tr>
+
+      <tal:block tal:define="header python: 'Compute Node: ${title}';
+                             dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-COMPUTER 0'}) ">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
+      </tal:block>
+
+      <tr>
+        <td colspan="3"><b tal:content="python: 'Add an Support Request'"> Menu Item </b></td>
+      </tr>
+
+      <tal:block define="menu_action python: 'Add Ticket'">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//input[@id="title"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//input[@id="title"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>type</td>
+        <td>//input[@id="title"]</td>
+        <td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0</td>
+      </tr>
+
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//textarea[@id="description"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>type</td>
+        <td>//textarea[@id="description"]</td>
+        <td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED DESCRIPTION</td>
+      </tr>
+
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//select[@id="resource"]</td>
+        <td></td>
+      </tr>
+
+      <tr>
+        <td>select</td>
+        <td>//select[@id="resource"]</td>
+        <td>Complaint</td>
+      </tr>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
+
+      <tal:block tal:define="notification_configuration python: {'class': 'success',
+                                                           'text': 'New Ticket created.'}">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_notification" />
+      </tal:block>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_content_loaded" />
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
+
+      <tal:block define="menu_item python: 'Servers'; header menu_item">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>click</td>
+        <td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
+        <td></td>
+      </tr>
+      
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>click</td>
+        <td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0"]</td>
+        <td></td>
+      </tr>
+
+      <tal:block tal:define="header python: 'Support Request : ${title}';
+                             dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>verifyTextPresent</td>
+        <td>Demo User Functional</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>verifyTextPresent</td>
+        <td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0</td>
+        <td></td>
+      </tr>
+
+      <tr>
+        <td>verifyTextPresent</td>
+        <td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED DESCRIPTION</td>
+        <td></td>
+      </tr>
+
+      <tal:block tal:define="menu_action python: 'Add'">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
+      </tal:block>
+
+      <tal:block tal:define="header python: 'New Message'">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//textarea[@id="text_content"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//textarea[@id="text_content"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>type</td>
+        <td>//textarea[@id="text_content"]</td>
+        <td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED NEW MESSAGE</td>
+      </tr>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_content_loaded" />
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
+
+      <tal:block define="menu_item python: 'Servers'; header menu_item">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>click</td>
+        <td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
+        <td></td>
+      </tr>
+
+      <tal:block tal:define="header python: 'Compute Node: ${title}';
+                             dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-COMPUTER 0'}) ">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
+      </tal:block>
+
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>click</td>
+        <td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0"]</td>
+        <td></td>
+      </tr>
+
+      <tal:block tal:define="header python: 'Support Request : ${title}';
+                             dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED 0'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(2)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '2'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>verifyTextPresent</td>
+        <td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVER-RELATED NEW MESSAGE</td>
+        <td></td>
+      </tr>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
+
+      <tal:block define="menu_item python: 'Servers'; header menu_item">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>click</td>
+        <td>//a[text()="TEST-SLAPOSJS-COMPUTER 0"]</td>
+        <td></td>
+      </tr>
+
+      <tal:block tal:define="header python: 'Compute Node: ${title}';
+                             dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-COMPUTER 0'}) ">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
+      </tal:block>
+
+      <tr>
+        <td colspan="3"><b> Update Allocation Scope</b></td>
+      </tr>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//select[@id="allocation_scope"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//select[@id="allocation_scope"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>select</td>
+        <td>//select[@id="allocation_scope"]</td>
+        <td tal:content="python: '%s' % (here.Base_translateString('Closed forever', lang=lang))"></td>
+      </tr>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/save" />
+
+      <tal:block define="menu_item python: 'Servers'; header menu_item">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
+      </tal:block>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
+
+      <tal:block define="menu_item python: 'Servers'; header menu_item">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(0)', 'footer': 'No records'}">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_logout" />
+
+    </tbody>
+  </table>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_upgradeComputeNode.xml b/master/bt5/slapos_jio_ui_test/PathTemplateItem/portal_tests/slaposjs_zuite/testSlapOSJSServiceTicketRelated.xml
similarity index 55%
rename from master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_upgradeComputeNode.xml
rename to master/bt5/slapos_jio_ui_test/PathTemplateItem/portal_tests/slaposjs_zuite/testSlapOSJSServiceTicketRelated.xml
index 07cd741f7f83047c75dbeaa455b6c1c9d28d159a..dbe90d0ad155ae2a2bbcb4438c04ef9f65050124 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_upgradeComputeNode.xml
+++ b/master/bt5/slapos_jio_ui_test/PathTemplateItem/portal_tests/slaposjs_zuite/testSlapOSJSServiceTicketRelated.xml
@@ -2,14 +2,10 @@
 <ZopeData>
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
-      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+      <global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
     </pickle>
     <pickle>
       <dictionary>
-        <item>
-            <key> <string>Script_magic</string> </key>
-            <value> <int>3</int> </value>
-        </item>
         <item>
             <key> <string>_bind_names</string> </key>
             <value>
@@ -24,18 +20,6 @@
                         <key> <string>_asgns</string> </key>
                         <value>
                           <dictionary>
-                            <item>
-                                <key> <string>name_container</string> </key>
-                                <value> <string>container</string> </value>
-                            </item>
-                            <item>
-                                <key> <string>name_context</string> </key>
-                                <value> <string>context</string> </value>
-                            </item>
-                            <item>
-                                <key> <string>name_m_self</string> </key>
-                                <value> <string>script</string> </value>
-                            </item>
                             <item>
                                 <key> <string>name_subpath</string> </key>
                                 <value> <string>traverse_subpath</string> </value>
@@ -49,12 +33,24 @@
             </value>
         </item>
         <item>
-            <key> <string>_params</string> </key>
-            <value> <string></string> </value>
+            <key> <string>content_type</string> </key>
+            <value> <string>text/html</string> </value>
+        </item>
+        <item>
+            <key> <string>expand</string> </key>
+            <value> <int>0</int> </value>
         </item>
         <item>
             <key> <string>id</string> </key>
-            <value> <string>UpgradeDecision_upgradeComputeNode</string> </value>
+            <value> <string>testSlapOSJSServiceTicketRelated</string> </value>
+        </item>
+        <item>
+            <key> <string>output_encoding</string> </key>
+            <value> <string>utf-8</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <unicode></unicode> </value>
         </item>
       </dictionary>
     </pickle>
diff --git a/master/bt5/slapos_jio_ui_test/PathTemplateItem/portal_tests/slaposjs_zuite/testSlapOSJSServiceTicketRelated.zpt b/master/bt5/slapos_jio_ui_test/PathTemplateItem/portal_tests/slaposjs_zuite/testSlapOSJSServiceTicketRelated.zpt
new file mode 100644
index 0000000000000000000000000000000000000000..8fd13df4614c91c3662a34d908229fa15919a785
--- /dev/null
+++ b/master/bt5/slapos_jio_ui_test/PathTemplateItem/portal_tests/slaposjs_zuite/testSlapOSJSServiceTicketRelated.zpt
@@ -0,0 +1,500 @@
+<html xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal">
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+  <title>Test SlapOS JS Service</title>
+</head>
+
+<body>
+  <table cellpadding="1" cellspacing="1" border="1">
+    <thead>
+      <tr>
+        <td rowspan="1" colspan="3">Test SlapOS JS Service</td>
+      </tr>
+    </thead>
+    <tbody>
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_init" />
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/set_default_available_language"/>
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_login" />
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_front_page" />
+
+      <tal:block define="menu_item python: 'Services'; header menu_item">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(0)', 'footer': 'No records'}">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tal:block define="menu_action python: 'Add'">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
+      </tal:block>
+
+
+      <tr>
+        <td colspan="3"><b> Request a Software </b></td>
+      </tr>
+
+      <tal:block define="software_product python: 'Frontend'">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/select_software_product" />
+      </tal:block>
+
+      <tal:block define="software_release python: 'Frontend'">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/select_software_release" />
+      </tal:block>
+
+      <tr>
+        <td colspan="3"><b> Fill Request form </b></td>
+      </tr>
+
+      <tal:block tal:define="header python: '3/3 Request Service: ${title}';
+                             dummy python: context.REQUEST.set('mapping', {'title': 'Frontend'}) ">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//input[@id="title"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//input[@id="title"]</td>
+        <td></td>
+      </tr>
+
+      <tr>
+        <td>type</td>
+        <td>//input[@id="title"]</td>
+        <td>TEST-SLAPOSJS-SERVICE-FRONTEND 0</td>
+      </tr>
+
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//div[contains(@data-gadget-url,
+          'gadget_erp5_page_slap_parameter_form.html')]//select[@name="software_type"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//div[contains(@data-gadget-url,
+          'gadget_erp5_page_slap_parameter_form.html')]//select[@name="software_type"]</td>
+        <td></td>
+      </tr>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//div[contains(@data-gadget-url,
+          'gadget_erp5_page_slap_parameter_form.html')]//select[@name="software_type"]//option[text()="Custom Personal"]
+        </td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//div[contains(@data-gadget-url,
+          'gadget_erp5_page_slap_parameter_form.html')]//select[@name="software_type"]//option[text()="Custom Personal"]
+        </td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>select</td>
+        <td>//div[contains(@data-gadget-url,
+          'gadget_erp5_page_slap_parameter_form.html')]//select[@name="software_type"]</td>
+        <td>Custom Personal</td>
+      </tr>
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//input[@name="//domain"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//input[@name="//domain"]</td>
+        <td></td>
+      </tr>
+
+      <tr>
+        <td>type</td>
+        <td>//input[@name="//domain"]</td>
+        <td>www.erp5.com</td>
+      </tr>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
+
+      <tal:block tal:define="notification_configuration python: {'class': 'success',
+                                                           'text': 'New service created.'}">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_notification" />
+      </tal:block>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
+
+      <tal:block define="menu_item python: 'Services'; header menu_item">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
+      </tal:block>
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//div[contains(@data-gadget-url,
+          'gadget_slapos_panel.html')]//img[contains(@src, 'gadget_slapos_panel.png?format=png')]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//div[contains(@data-gadget-url,
+          'gadget_slapos_panel.html')]//img[contains(@src, 'gadget_slapos_panel.png?format=png')]</td>
+        <td></td>
+      </tr>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>click</td>
+        <td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
+        <td></td>
+      </tr>
+      <tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
+        <td>waitForElementPresent</td>
+        <td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
+        <td></td>
+      </tr>
+      <tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
+        <td>assertElementPresent</td>
+        <td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
+        <td></td>
+      </tr>
+
+      <tr>
+        <td colspan="3"><b tal:content="python: 'Add an Support Request'"> Menu Item </b></td>
+      </tr>
+
+      <tal:block define="menu_action python: 'Add Ticket'">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//input[@id="title"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//input[@id="title"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>type</td>
+        <td>//input[@id="title"]</td>
+        <td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0</td>
+      </tr>
+
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//textarea[@id="description"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>type</td>
+        <td>//textarea[@id="description"]</td>
+        <td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED DESCRIPTION</td>
+      </tr>
+
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//select[@id="resource"]</td>
+        <td></td>
+      </tr>
+
+      <tr>
+        <td>select</td>
+        <td>//select[@id="resource"]</td>
+        <td>Complaint</td>
+      </tr>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
+
+      <tal:block tal:define="notification_configuration python: {'class': 'success',
+                                                           'text': 'New Ticket created.'}">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_notification" />
+      </tal:block>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_content_loaded" />
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
+
+      <tal:block define="menu_item python: 'Services'; header menu_item">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>click</td>
+        <td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
+        <td></td>
+      </tr>
+      
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>click</td>
+        <td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0"]</td>
+        <td></td>
+      </tr>
+
+      <tal:block tal:define="header python: 'Support Request : ${title}';
+                             dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>verifyTextPresent</td>
+        <td>Demo User Functional</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>verifyTextPresent</td>
+        <td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0</td>
+        <td></td>
+      </tr>
+
+      <tr>
+        <td>verifyTextPresent</td>
+        <td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED DESCRIPTION</td>
+        <td></td>
+      </tr>
+
+      <tal:block tal:define="menu_action python: 'Add'">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
+      </tal:block>
+
+      <tal:block tal:define="header python: 'New Message'">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//textarea[@id="text_content"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//textarea[@id="text_content"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>type</td>
+        <td>//textarea[@id="text_content"]</td>
+        <td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED NEW MESSAGE</td>
+      </tr>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_content_loaded" />
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
+
+      <tal:block define="menu_item python: 'Services'; header menu_item">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>click</td>
+        <td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
+        <td></td>
+      </tr>
+
+      <tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
+        <td>waitForElementPresent</td>
+        <td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
+        <td></td>
+      </tr>
+      <tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
+        <td>assertElementPresent</td>
+        <td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
+        <td></td>
+      </tr>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>click</td>
+        <td>//a[text()="TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0"]</td>
+        <td></td>
+      </tr>
+
+      <tal:block tal:define="header python: 'Support Request : ${title}';
+                             dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED 0'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(2)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '2'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//div[contains(@data-gadget-url, 'gadget_slapos_event_discussion_entry.html')]//div[@class="slapos-event-discussion-message-header"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>verifyTextPresent</td>
+        <td>TEST-SLAPOSJS-SUPPORT-REQUEST-SERVICE-RELATED NEW MESSAGE</td>
+        <td></td>
+      </tr>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
+
+      <tal:block define="menu_item python: 'Services'; header menu_item">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
+                             dummy python: context.REQUEST.set('mapping', {'count': '1'})">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+
+      <tr>
+        <td>waitForElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>assertElementPresent</td>
+        <td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
+        <td></td>
+      </tr>
+      <tr>
+        <td>click</td>
+        <td>//a[text()="TEST-SLAPOSJS-SERVICE-FRONTEND 0"]</td>
+        <td></td>
+      </tr>
+
+      <tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
+        <td>waitForElementPresent</td>
+        <td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
+        <td></td>
+      </tr>
+      <tr tal:define="dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'})">
+        <td>assertElementPresent</td>
+        <td tal:content="python: '//a[@data-i18n= \'%s\']' % (here.Base_translateString('Instance Tree: ${title}', mapping=context.REQUEST.get('mapping', {}), lang=lang))"></td>
+        <td></td>
+      </tr>
+
+      <tal:block define="menu_action python: 'Destroy'">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
+      </tal:block>
+
+      <tal:block tal:define="header python: 'Destroy Instance Tree: ${title}';
+                             dummy python: context.REQUEST.set('mapping', {'title': 'TEST-SLAPOSJS-SERVICE-FRONTEND 0'}) ">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
+      </tal:block>
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
+
+      <tal:block tal:define="notification_configuration python: {'class': 'success',
+                                                           'text': 'Service is Destroyed.'}">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_notification" />
+      </tal:block>
+
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
+
+      <tal:block define="menu_item python: 'Services'; header menu_item">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item" />
+      </tal:block>
+
+      <tal:block tal:define="pagination_configuration python: {'header': '(0)', 'footer': 'No records'}">
+        <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
+      </tal:block>
+      <tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_logout" />
+
+    </tbody>
+  </table>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/master/bt5/slapos_pdm/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml b/master/bt5/slapos_pdm/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
index 239e6c011a1199eb33466dbb61718595b39d9cc4..4fd9e31ed4ce62ec0c208dfdf8f6d36e21c66dae 100644
--- a/master/bt5/slapos_pdm/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
+++ b/master/bt5/slapos_pdm/PortalTypeWorkflowChainTemplateItem/workflow_chain_type.xml
@@ -5,6 +5,6 @@
  </chain>
  <chain>
   <type>Upgrade Decision</type>
-  <workflow>edit_workflow, ticket_interaction_workflow, upgrade_decision_workflow</workflow>
+  <workflow>edit_workflow, ticket_interaction_workflow, upgrade_decision_workflow, upgrade_slap_interface_workflow</workflow>
  </chain>
 </workflow_chain>
\ No newline at end of file
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/Alarm_cancelUpgradeDecision.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/Alarm_cancelUpgradeDecision.py
index 3f57491baf524ff3df7ecc939c9ecd105b7e37f7..ed977534810522aea5fa53c4dfa54be9938dd6c7 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/Alarm_cancelUpgradeDecision.py
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/Alarm_cancelUpgradeDecision.py
@@ -1,6 +1,4 @@
 portal = context.getPortalObject()
-
-
 portal.portal_catalog.searchAndActivate(
   portal_type="Upgrade Decision Line",
   simulation_state=["confirmed", "draft", "planned"],
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/ComputeNode_checkAndCreateUpgradeDecision.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/ComputeNode_checkAndCreateUpgradeDecision.py
index be387352cad6f8bca8f3bc0e6e7965845f4df960..42d80e0ad1f808748f4260006c0ec56e19c6a69f 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/ComputeNode_checkAndCreateUpgradeDecision.py
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/ComputeNode_checkAndCreateUpgradeDecision.py
@@ -41,22 +41,18 @@ for software_release in software_release_list:
     # If exist upgrade decision in progress try to cancel it
     decision_in_progress = newer_release.\
             SoftwareRelease_getUpgradeDecisionInProgress(compute_node.getUid())
-    if decision_in_progress and \
-        not decision_in_progress.UpgradeDecision_tryToCancel(
-          newer_release.getUrlString()):
-      continue
+    if decision_in_progress:
+      decision_in_progress.reviewRegistration(
+        software_release_url=newer_release.getUrlString())
+      if decision_in_progress.getSimulationState() != "cancelled":
+        continue
 
     upgrade_decision = newer_release.SoftwareRelease_createUpgradeDecision(
         source_url=compute_node.getRelativeUrl(),
         title=title)
 
-    if context.getUpgradeScope() == "auto":
-      upgrade_decision.start()
-    elif context.getUpgradeScope("ask_confirmation") == "ask_confirmation" \
-      and upgrade_decision.getSimulationState() != "planned":
-      upgrade_decision.plan()
-
-    upgrade_decision.setStartDate(DateTime())
+    upgrade_decision.approveRegistration(
+      upgrade_scope=compute_node.getUpgradeScope("ask_confirmation"))
     upgrade_decision_list.append(upgrade_decision)
 
 return upgrade_decision_list
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/InstanceTree_createUpgradeDecision.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/InstanceTree_createUpgradeDecision.py
index 8b3057b3bc12cbc34ec81cbf896811ddf9b63b4a..a867a8236a9dc6af24b38425ee87642c2b4b1671 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/InstanceTree_createUpgradeDecision.py
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/InstanceTree_createUpgradeDecision.py
@@ -2,7 +2,7 @@ from DateTime import DateTime
 portal = context.getPortalObject()
 
 instance_tree = context
-upgrade_scope = context.getUpgradeScope()
+upgrade_scope = context.getUpgradeScope("ask_confirmation")
 if upgrade_scope in ["never", "disabled"]:
   return
 
@@ -22,7 +22,6 @@ if instance_tree.getSlapState() == "destroy_requested":
   return
 
 tag = "%s_requestUpgradeDecisionCreation_inProgress" % instance_tree.getUid()
-activate_kw = {'tag': tag}
 if portal.portal_activities.countMessageWithTag(tag) > 0:
   # nothing to do
   return
@@ -52,22 +51,18 @@ if newer_release is None:
 decision_in_progress = newer_release.\
     SoftwareRelease_getUpgradeDecisionInProgress(instance_tree.getUid())
 
-if decision_in_progress and \
-    not decision_in_progress.UpgradeDecision_tryToCancel(
-      newer_release.getUrlString()):
-  return
+if decision_in_progress:
+  decision_in_progress.reviewRegistration(
+    software_release_url=newer_release.getUrlString())
+  if decision_in_progress.getSimulationState() != "cancelled":
+    return
 
 upgrade_decision = newer_release.SoftwareRelease_createUpgradeDecision(
   source_url=instance_tree.getRelativeUrl(),
   title=decision_title
 )
-with upgrade_decision.defaultActivateParameterDict(activate_kw):
-  upgrade_decision.plan()
-  upgrade_decision.setStartDate(DateTime())
-  if upgrade_scope == "auto":
-    upgrade_decision.start()
 
-# Prevent concurrent transaction to create 2 upgrade decision for the same instance_tree
-instance_tree.serialize()
+upgrade_decision.approveRegistration(
+  upgrade_scope=upgrade_scope)
 
 return upgrade_decision
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecisionLine_cancel.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecisionLine_cancel.py
index a05a8dee3ded0720d4f8977d966d4d7143d7581f..e7d6362e65a972d7de2256b1133525c6c2caeb1d 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecisionLine_cancel.py
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecisionLine_cancel.py
@@ -1,41 +1 @@
-instance_tree = context.getAggregateValue(portal_type="Instance Tree")
-
-software_release = context.getAggregateValue(portal_type="Software Release")
-
-upgrade_decision = context.getParentValue()
-
-if upgrade_decision.getSimulationState() == "cancelled":
-  return
-
-if software_release.getValidationState() == "archived":
-  upgrade_decision.cancel(comment="Software Release is archived.")
-  return
-
-if instance_tree is not None:
-  if instance_tree.getUpgradeScope() in ['never', 'disabled']:
-    upgrade_decision.cancel("Upgrade scope was disabled on the related Instance Tree")
-
-  elif instance_tree.getSlapState() == "destroy_requested":
-    upgrade_decision.cancel(comment="Instance Tree is destroyed.")
-
-  elif instance_tree.getUrlString() == software_release.getUrlString():
-    upgrade_decision.cancel(comment="Instance tree is already upgraded.")
-
-  return
-
-compute_node = context.getAggregateValue(portal_type="Compute Node")
-if compute_node is not None:
-  if compute_node.getUpgradeScope() in ['never', 'disabled']:
-    upgrade_decision.cancel("Upgrade scope was disabled on the related Instance Tree")
-    return
-
-  elif compute_node.getAllocationScope() in ["closed/forever", "closed/termination"]:
-    upgrade_decision.cancel(comment="Compute Node is closed.")
-    return
-
-  already_deployed = len(context.portal_catalog(limit=1,
-    portal_type="Compute Partition",
-    parent_reference=compute_node.getReference(),
-    software_release_url=software_release.getUrlString()))
-  if already_deployed:
-    upgrade_decision.cancel(comment="Compute Node already has the software release")
+context.getParentValue().reviewUpgrade()
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getAggregateValue.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getAggregateValue.py
new file mode 100644
index 0000000000000000000000000000000000000000..9e5b0e26cdecfd56c58e27e8d5567ffb6c124608
--- /dev/null
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getAggregateValue.py
@@ -0,0 +1,15 @@
+document_list = []
+for decision_line in context.contentValues():
+  try:
+    document_list.extend(
+      decision_line.getAggregateValueList(portal_type=document_portal_type))
+  except:
+    raise ValueError(context)
+
+if len(document_list) > 1: 
+  raise ValueError("It is only allowed to have more them 1 %s" % document_list)
+
+if len(document_list) == 0:
+  return None
+
+return document_list[0]
diff --git a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.xml b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getAggregateValue.xml
similarity index 93%
rename from master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.xml
rename to master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getAggregateValue.xml
index 3629c9852601b025ff7e818452e8b586cb86a867..e2de53d76cb27863c04e7c2ccc4e04d31492c54c 100644
--- a/master/bt5/slapos_crm/SkinTemplateItem/portal_skins/slapos_crm_monitoring/Base_generateSupportRequestForSlapOS.xml
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getAggregateValue.xml
@@ -50,11 +50,11 @@
         </item>
         <item>
             <key> <string>_params</string> </key>
-            <value> <string>title, description, source_relative_url</string> </value>
+            <value> <string>document_portal_type="Instance Tree"</string> </value>
         </item>
         <item>
             <key> <string>id</string> </key>
-            <value> <string>Base_generateSupportRequestForSlapOS</string> </value>
+            <value> <string>UpgradeDecision_getAggregateValue</string> </value>
         </item>
       </dictionary>
     </pickle>
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getComputeNode.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getComputeNode.py
deleted file mode 100644
index 11a02a7a9e19860aec44d406483feb6df41c55f8..0000000000000000000000000000000000000000
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getComputeNode.py
+++ /dev/null
@@ -1,13 +0,0 @@
-compute_node_list = []
-for decision_line in context.contentValues():
-  compute_node_list.extend(
-    decision_line.getAggregateValueList(portal_type="Compute Node"))
-
-if len(compute_node_list) > 1: 
-  raise ValueError("It is only allowed to have more them 1 Compute Node")
-
-if len(compute_node_list) == 0:
-  return None
-
-
-return compute_node_list[0]
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getInstanceTree.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getInstanceTree.py
deleted file mode 100644
index 57f4867cdca4a74c600ec622ad1bc73e0be709b4..0000000000000000000000000000000000000000
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getInstanceTree.py
+++ /dev/null
@@ -1,13 +0,0 @@
-instance_tree_list = []
-for decision_line in context.contentValues():
-  instance_tree_list.extend(
-    decision_line.getAggregateValueList(portal_type="Instance Tree"))
-
-if len(instance_tree_list) > 1: 
-  raise ValueError("It is only allowed to have more them 1 Instance Tree")
-
-if len(instance_tree_list) == 0:
-  return None
-
-
-return instance_tree_list[0]
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getSoftwareRelease.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getSoftwareRelease.py
deleted file mode 100644
index ab944a937f324dd7750be882d932744db199e0c5..0000000000000000000000000000000000000000
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getSoftwareRelease.py
+++ /dev/null
@@ -1,13 +0,0 @@
-software_release_list = []
-for decision_line in context.contentValues():
-  software_release_list.extend(
-    decision_line.getAggregateValueList(portal_type="Software Release"))
-
-if len(software_release_list) > 1: 
-  raise ValueError("It is only allowed to have more them 1 Software Release")
-
-if len(software_release_list) == 0:
-  return None
-
-
-return software_release_list[0]
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_isUpgradeFinished.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_isUpgradeFinished.py
index 4e2aecb846a02cabd4395cfd221bd1fefbb2fdc6..288a88dc1eba1b6913eaa3646c6b24794c52674a 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_isUpgradeFinished.py
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_isUpgradeFinished.py
@@ -1,8 +1,8 @@
 portal = context.getPortalObject()
 
-instance_tree = context.UpgradeDecision_getInstanceTree()
-compute_node = context.UpgradeDecision_getComputeNode()
-software_release = context.UpgradeDecision_getSoftwareRelease()
+instance_tree = context.UpgradeDecision_getAggregateValue("Instance Tree")
+compute_node = context.UpgradeDecision_getAggregateValue("Compute Node")
+software_release = context.UpgradeDecision_getAggregateValue("Software Release")
 
 if instance_tree is not None:
   if instance_tree.getUrlString() == software_release.getUrlString():
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_notify.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_notify.py
index 9cdcd451ae5bb974da6b1e0e08fb7bac76582c63..194f605802ae4d9827002d0a45e414271c62b8b8 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_notify.py
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_notify.py
@@ -1,8 +1,11 @@
 from DateTime import DateTime
 
+# Review if the upgrade is applicable before notify.
+context.reviewUpgrade()
+
 if context.getSimulationState() != 'planned':
   # XXX Don't notify the ones which are not planned.
-  return 
+  return
 
 portal = context.getPortalObject()
 
@@ -10,9 +13,9 @@ person = context.getDestinationDecisionValue(portal_type="Person")
 if not person:
   raise ValueError("Inconsistent Upgrade Decision, No Destination Decision")
 
-instance_tree = context.UpgradeDecision_getInstanceTree()
-compute_node = context.UpgradeDecision_getComputeNode()
-software_release = context.UpgradeDecision_getSoftwareRelease()
+instance_tree = context.UpgradeDecision_getAggregateValue("Instance Tree")
+compute_node = context.UpgradeDecision_getAggregateValue("Compute Node")
+software_release = context.UpgradeDecision_getAggregateValue("Software Release")
 software_product_title = software_release.getAggregateTitle(
                                portal_type="Software Product")
 
@@ -21,8 +24,8 @@ mapping_dict = {
   'software_release_name': software_release.getTitle(),
   'software_release_reference': software_release.getReference(),
   'new_software_release_url': software_release.getUrlString(),
-
 }
+
 if instance_tree is not None:
   notification_message_reference = 'slapos-upgrade-instance-tree.notification'
   title = "New Upgrade available for %s" % instance_tree.getTitle()
@@ -30,11 +33,8 @@ if instance_tree is not None:
      'instance_tree_title': instance_tree.getTitle(),
      'old_software_release_url': instance_tree.getUrlString()})
 
-
 elif compute_node is not None:
-
   notification_message_reference = 'slapos-upgrade-compute-node.notification' 
-
   title = "New Software available for Installation at %s" % compute_node.getTitle()
   mapping_dict.update(**{'compute_node_title': compute_node.getTitle(),
                          'compute_node_reference': compute_node.getReference()})
@@ -49,8 +49,10 @@ notification_message = portal.portal_notifications.getDocumentValue(
 message = notification_message.asEntireHTML(
             substitution_method_parameter_dict={'mapping_dict': mapping_dict})
 
-event = context.SupportRequest_trySendNotificationMessage(title,
-              message, person.getRelativeUrl())
+context.notify(message_title=title,
+                     message=message,
+                     destination_relative_url=person.getRelativeUrl())
+event = context.REQUEST.get("upgrade_decision_notified_item")
 
 if event is not None:
   context.confirm()
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_notifyDelivered.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_notifyDelivered.py
index 46b07d70ab76756f21060e051c3f6819c11949bb..9a57990ae6a5c86de8a734e6c465f7010643cad8 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_notifyDelivered.py
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_notifyDelivered.py
@@ -12,9 +12,10 @@ person = context.getDestinationDecisionValue(portal_type="Person")
 if not person:
   raise ValueError("Inconsistent Upgrade Decision, No Destination Decision")
 
-instance_tree = context.UpgradeDecision_getInstanceTree()
-compute_node = context.UpgradeDecision_getComputeNode()
-software_release = context.UpgradeDecision_getSoftwareRelease()
+
+instance_tree = context.UpgradeDecision_getAggregateValue("Instance Tree")
+compute_node = context.UpgradeDecision_getAggregateValue("Compute Node")
+software_release = context.UpgradeDecision_getAggregateValue("Software Release")
 software_product_title = software_release.getAggregateTitle(
                                portal_type="Software Product")
 
@@ -51,8 +52,10 @@ notification_message = portal.portal_notifications.getDocumentValue(
 message = notification_message.asEntireHTML(
             substitution_method_parameter_dict={'mapping_dict': mapping_dict})
 
-event = context.SupportRequest_trySendNotificationMessage(title,
-              message, person.getRelativeUrl())
+context.notify(message_title=title,
+                     message=message,
+                     destination_relative_url=person.getRelativeUrl())
+event = context.REQUEST.get("upgrade_decision_notified_item")
 
 if event is not None:
   context.setStopDate(DateTime())
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_processUpgrade.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_processUpgrade.py
index 5a94a4b9ffd2a3fe737fa60d4ae22ee81566919b..0e3ffaf8c699cfa93d797178c09ce4d3cfb56887 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_processUpgrade.py
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_processUpgrade.py
@@ -1,7 +1 @@
-if context.UpgradeDecision_upgradeInstanceTree():
-  return True
-
-if context.UpgradeDecision_upgradeComputeNode():
-  return True
-
-return False
+return context.requestUpgrade()
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_processUpgrade.xml b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_processUpgrade.xml
index 511daee104c4fe077f5ca111292b2449bca3e2b3..04baf55bfd764505c60d8ceccd826567a9f2b37c 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_processUpgrade.xml
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_processUpgrade.xml
@@ -50,7 +50,7 @@
         </item>
         <item>
             <key> <string>_params</string> </key>
-            <value> <string>**kw</string> </value>
+            <value> <string></string> </value>
         </item>
         <item>
             <key> <string>id</string> </key>
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_tryToCancel.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_tryToCancel.py
deleted file mode 100644
index 6bc608571c633f15cf614270e50d512c8cceca74..0000000000000000000000000000000000000000
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_tryToCancel.py
+++ /dev/null
@@ -1,27 +0,0 @@
-upgrade_decision = context
-cancellable_state_list = ['confirmed', 'planned']
-require_state_list = ['rejected', 'confirmed', 'planned']
-simulation_state = upgrade_decision.getSimulationState()
-
-if simulation_state in require_state_list:
-  current_release = upgrade_decision.UpgradeDecision_getSoftwareRelease()
-  if not current_release:
-    # This upgrade decision is not valid
-    return False
-  instance_tree = upgrade_decision.UpgradeDecision_getInstanceTree()
-  if instance_tree is not None:
-    current_instance_tree_release = instance_tree.getUrlString()
-    if current_instance_tree_release == new_url_string:
-      if simulation_state in cancellable_state_list:
-        upgrade_decision.cancel()
-      return True
-
-  if current_release.getUrlString() == new_url_string:
-    # Cannot cancel because the software releases are the same
-    return False
-
-  if simulation_state in cancellable_state_list:
-    upgrade_decision.cancel()
-  return True
-else:
-  return False
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_tryToCancel.xml b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_tryToCancel.xml
deleted file mode 100644
index f5614268ecd9d1276f2836b735ee7b5ad46ca7de..0000000000000000000000000000000000000000
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_tryToCancel.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0"?>
-<ZopeData>
-  <record id="1" aka="AAAAAAAAAAE=">
-    <pickle>
-      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
-    </pickle>
-    <pickle>
-      <dictionary>
-        <item>
-            <key> <string>Script_magic</string> </key>
-            <value> <int>3</int> </value>
-        </item>
-        <item>
-            <key> <string>_bind_names</string> </key>
-            <value>
-              <object>
-                <klass>
-                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
-                </klass>
-                <tuple/>
-                <state>
-                  <dictionary>
-                    <item>
-                        <key> <string>_asgns</string> </key>
-                        <value>
-                          <dictionary>
-                            <item>
-                                <key> <string>name_container</string> </key>
-                                <value> <string>container</string> </value>
-                            </item>
-                            <item>
-                                <key> <string>name_context</string> </key>
-                                <value> <string>context</string> </value>
-                            </item>
-                            <item>
-                                <key> <string>name_m_self</string> </key>
-                                <value> <string>script</string> </value>
-                            </item>
-                            <item>
-                                <key> <string>name_subpath</string> </key>
-                                <value> <string>traverse_subpath</string> </value>
-                            </item>
-                          </dictionary>
-                        </value>
-                    </item>
-                  </dictionary>
-                </state>
-              </object>
-            </value>
-        </item>
-        <item>
-            <key> <string>_params</string> </key>
-            <value> <string>new_url_string</string> </value>
-        </item>
-        <item>
-            <key> <string>id</string> </key>
-            <value> <string>UpgradeDecision_tryToCancel</string> </value>
-        </item>
-      </dictionary>
-    </pickle>
-  </record>
-</ZopeData>
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_upgradeComputeNode.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_upgradeComputeNode.py
deleted file mode 100644
index 483b8f27b6fd63ea8bbccfb35214c5a651766e08..0000000000000000000000000000000000000000
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_upgradeComputeNode.py
+++ /dev/null
@@ -1,22 +0,0 @@
-if context.getSimulationState() != 'started':
-  # Update Decision is not on started state, Upgrade is not possible!
-  return False
-
-compute_node = context.UpgradeDecision_getComputeNode()
-software_release = context.UpgradeDecision_getSoftwareRelease()
-
-if compute_node is None:
-  return False
-
-if software_release is None:
-  return False 
-
-software_release_url = software_release.getUrlString()
-
-compute_node.requestSoftwareRelease(
-   software_release_url=software_release_url,
-   state="available")
-
-context.stop()
-
-return True
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_upgradeInstanceTree.py b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_upgradeInstanceTree.py
deleted file mode 100644
index 12ee86fd13ec56f32295de9e9339967be4439c32..0000000000000000000000000000000000000000
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_upgradeInstanceTree.py
+++ /dev/null
@@ -1,42 +0,0 @@
-if context.getSimulationState() != 'started':
-  # Update Decision is not on started state, Upgrade is not possible!
-  return False
-
-instance_tree = context.UpgradeDecision_getInstanceTree()
-software_release = context.UpgradeDecision_getSoftwareRelease()
-
-if instance_tree is None:
-  return False
-
-if software_release is None:
-  return False 
-
-software_release_url = software_release.getUrlString()
-person = instance_tree.getDestinationSectionValue(portal_type="Person")
-
-# Test if the Software is available at the ComputeNode.
-if not instance_tree.InstanceTree_isUpgradePossible(
-  software_release_url=software_release_url):
-  return
-
-status = instance_tree.getSlapState()
-if status == "start_requested":
-  state = "started"
-elif status == "stop_requested":
-  state = "stopped"
-elif status == "destroy_requested":
-  state = "destroyed"
-  
-person.requestSoftwareInstance(
-  state=state,
-  software_release=software_release_url,
-  software_title=instance_tree.getTitle(),
-  software_type=instance_tree.getSourceReference(),
-  instance_xml=instance_tree.getTextContent(),
-  sla_xml=instance_tree.getSlaXml(),
-  shared=instance_tree.isRootSlave()
-)
-
-context.stop()
-
-return True
diff --git a/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudUpgradeSlapInterfaceWorkflow.py b/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudUpgradeSlapInterfaceWorkflow.py
new file mode 100644
index 0000000000000000000000000000000000000000..3945e59421af44f32a7a3aaa7154b40676de7b70
--- /dev/null
+++ b/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudUpgradeSlapInterfaceWorkflow.py
@@ -0,0 +1,557 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+##############################################################################
+from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, simulate
+#from zExceptions import Unauthorized
+import transaction
+
+class TestSlapOSCoreProjectSlapInterfaceWorkflow(SlapOSTestCaseMixin):
+
+  def afterSetUp(self):
+    SlapOSTestCaseMixin.afterSetUp(self)
+    portal = self.getPortalObject()
+    
+    person_user = self.makePerson()
+    self.tic()
+    
+    self.login()
+    self.compute_node = self.portal.compute_node_module.template_compute_node\
+        .Base_createCloneDocument(batch_mode=1)
+    new_id = self.generateNewId()
+    self.compute_node.edit(
+      title="compute node %s" % (new_id, ),
+      reference="TESTCOMP-%s" % (new_id, ),
+      source_administration=person_user.getRelativeUrl()
+    )
+    self.compute_node.validate()
+
+    self.upgrade_decision = portal.upgrade_decision_module.newContent(
+      portal_type="Upgrade Decision",
+    )
+
+    # Value set by the init
+    self.assertTrue(self.upgrade_decision.getReference().startswith("UD-"),
+      "Reference don't start with UD- : %s" % self.upgrade_decision.getReference())
+
+    self.software_release = self._makeSoftwareRelease()
+    self.tic()
+
+  def _addUpgradeLine(self, aggregate):
+    self.upgrade_decision.newContent(
+      portal_type="Upgrade Decision Line",
+      aggregate_value_list=[self.software_release,
+                 aggregate]
+    )
+
+  def beforeTearDown(self):
+    transaction.abort()
+
+  def test_upgrade_decision_approveRegistration_no_line(self):
+    self.assertRaises(ValueError, self.upgrade_decision.approveRegistration)
+
+  def test_upgrade_decision_approveRegistration_no_aggregate(self):
+    self.upgrade_decision.newContent(
+      portal_type="Upgrade Decision Line",
+      aggregate=self.software_release.getRelativeUrl()
+    )
+    self.assertRaises(ValueError, self.upgrade_decision.approveRegistration)
+
+  def test_upgrade_decision_approveRegistration_no_upgrade_scope(self):
+    self._addUpgradeLine(self.compute_node)
+    self.assertRaises(TypeError, self.upgrade_decision.approveRegistration)
+
+  def test_upgrade_decision_approveRegistration_computer(self):
+    self._addUpgradeLine(self.compute_node)
+    self.upgrade_decision.approveRegistration(
+      upgrade_scope="ask_confirmation"
+    )
+    self.assertEqual("planned",
+      self.upgrade_decision.getSimulationState())
+    
+    self.commit()
+    tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
+    self.assertEqual(2,
+      self.portal.portal_activities.countMessageWithTag(tag))
+
+    # Call again does nothing
+    self.upgrade_decision.approveRegistration(
+      upgrade_scope="ask_confirmation"
+    )
+    self.assertEqual("planned",
+      self.upgrade_decision.getSimulationState())
+    
+    self.commit()
+    tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
+    self.assertEqual(2,
+      self.portal.portal_activities.countMessageWithTag(tag))
+
+    self.tic()
+    # Call again does nothing again
+    self.upgrade_decision.approveRegistration(
+      upgrade_scope="ask_confirmation"
+    )
+    self.assertEqual("planned",
+      self.upgrade_decision.getSimulationState())
+    
+    self.commit()
+    tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
+    self.assertEqual(2,
+      self.portal.portal_activities.countMessageWithTag(tag))
+
+  def test_upgrade_decision_approveRegistration_instance_tree(self):
+    self._makeTree()
+    self._addUpgradeLine(self.instance_tree)
+    self.upgrade_decision.approveRegistration(
+      upgrade_scope="ask_confirmation"
+    )
+    self.assertEqual("planned",
+      self.upgrade_decision.getSimulationState())
+    
+    self.commit()
+    tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
+    self.assertEqual(2,
+      self.portal.portal_activities.countMessageWithTag(tag))
+
+    # Call again does nothing
+    self.upgrade_decision.approveRegistration(
+      upgrade_scope="ask_confirmation"
+    )
+    self.assertEqual("planned",
+      self.upgrade_decision.getSimulationState())
+    
+    self.commit()
+    tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
+    self.assertEqual(2,
+      self.portal.portal_activities.countMessageWithTag(tag))
+
+    self.tic()
+    # Call again does nothing again
+    self.upgrade_decision.approveRegistration(
+      upgrade_scope="ask_confirmation"
+    )
+    self.assertEqual("planned",
+      self.upgrade_decision.getSimulationState())
+    
+    self.commit()
+    tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
+    self.assertEqual(2,
+      self.portal.portal_activities.countMessageWithTag(tag))
+
+
+  def test_upgrade_decision_approveRegistration_computer_auto(self):
+    self._addUpgradeLine(self.compute_node)
+    self.upgrade_decision.approveRegistration(
+      upgrade_scope="auto"
+    )
+    self.assertEqual("started",
+      self.upgrade_decision.getSimulationState())
+    
+    self.commit()
+    tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
+    self.assertEqual(2,
+      self.portal.portal_activities.countMessageWithTag(tag))
+
+    # Call again does nothing
+    self.upgrade_decision.approveRegistration(
+      upgrade_scope="auto"
+    )
+    self.assertEqual("started",
+      self.upgrade_decision.getSimulationState())
+    
+    self.commit()
+    tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
+    self.assertEqual(2,
+      self.portal.portal_activities.countMessageWithTag(tag))
+
+    self.tic()
+    # Call again does nothing again
+    self.upgrade_decision.approveRegistration(
+      upgrade_scope="auto"
+    )
+    self.assertEqual("started",
+      self.upgrade_decision.getSimulationState())
+    
+    self.commit()
+    tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.compute_node.getUid()
+    self.assertEqual(2,
+      self.portal.portal_activities.countMessageWithTag(tag))
+
+  def test_upgrade_decision_approveRegistration_instance_tree_auto(self):
+    self._makeTree()
+    self._addUpgradeLine(self.instance_tree)
+    self.upgrade_decision.approveRegistration(
+      upgrade_scope="auto"
+    )
+    self.assertEqual("started",
+      self.upgrade_decision.getSimulationState())
+    
+    self.commit()
+    tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
+    self.assertEqual(2,
+      self.portal.portal_activities.countMessageWithTag(tag))
+
+    # Call again does nothing
+    self.upgrade_decision.approveRegistration(
+      upgrade_scope="auto"
+    )
+    self.assertEqual("started",
+      self.upgrade_decision.getSimulationState())
+    
+    self.commit()
+    tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
+    self.assertEqual(2,
+      self.portal.portal_activities.countMessageWithTag(tag))
+
+    self.tic()
+    # Call again does nothing again
+    # Call again does nothing
+    self.upgrade_decision.approveRegistration(
+      upgrade_scope="auto"
+    )
+    self.assertEqual("started",
+      self.upgrade_decision.getSimulationState())
+    
+    self.commit()
+    tag = "%s_requestUpgradeDecisionCreation_inProgress" % self.instance_tree.getUid()
+    self.assertEqual(2,
+      self.portal.portal_activities.countMessageWithTag(tag))
+
+  def test_upgrade_decision_reviewRegistration_no_software_release_url(self):
+    self.assertRaises(TypeError, self.upgrade_decision.reviewRegistration)
+
+  def test_upgrade_decision_reviewRegistration_draft(self):
+    # Do nothing as draft
+    software_release = self.generateNewSoftwareReleaseUrl()
+    self.upgrade_decision.reviewRegistration(software_release_url=software_release)
+
+  def test_upgrade_decision_reviewRegistration(self):
+    self._addUpgradeLine(self.compute_node)
+    software_release = self.generateNewSoftwareReleaseUrl()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=software_release)
+
+    self.assertEqual("draft",
+      self.upgrade_decision.getSimulationState())
+
+    self.upgrade_decision.plan()
+    self.tic()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=software_release)
+
+    self.assertEqual("cancelled",
+      self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_reviewRegistration_confirm(self):
+    self._addUpgradeLine(self.compute_node)
+    software_release = self.generateNewSoftwareReleaseUrl()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=software_release)
+
+    self.assertEqual("draft",
+      self.upgrade_decision.getSimulationState())
+
+    self.upgrade_decision.confirm()
+    self.tic()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=software_release)
+
+    self.assertEqual("cancelled",
+      self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_reviewRegistration_rejected(self):
+    self._addUpgradeLine(self.compute_node)
+    software_release = self.generateNewSoftwareReleaseUrl()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=software_release)
+
+    self.assertEqual("draft",
+      self.upgrade_decision.getSimulationState())
+
+    self.upgrade_decision.reject()
+    self.tic()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=software_release)
+
+    self.assertEqual("rejected",
+      self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_reviewRegistration_same_url(self):
+    self._addUpgradeLine(self.compute_node)
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=self.software_release.getUrlString())
+
+    self.assertEqual("draft",
+      self.upgrade_decision.getSimulationState())
+
+    self.upgrade_decision.plan()
+    self.tic()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=self.software_release.getUrlString())
+
+    self.assertEqual("planned",
+      self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_reviewRegistration_confirm_same_url(self):
+    self._addUpgradeLine(self.compute_node)
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=self.software_release.getUrlString())
+
+    self.assertEqual("draft",
+      self.upgrade_decision.getSimulationState())
+
+    self.upgrade_decision.confirm()
+    self.tic()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=self.software_release.getUrlString())
+
+    self.assertEqual("confirmed",
+      self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_reviewRegistration_rejected_same_url(self):
+    self._addUpgradeLine(self.compute_node)
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=self.software_release.getUrlString())
+
+    self.assertEqual("draft",
+      self.upgrade_decision.getSimulationState())
+
+    self.upgrade_decision.reject()
+    self.tic()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=self.software_release.getUrlString())
+
+    self.assertEqual("rejected",
+      self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_reviewRegistration_started(self):
+    self._addUpgradeLine(self.compute_node)
+    software_release = self.generateNewSoftwareReleaseUrl()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=software_release)
+
+    self.assertEqual("draft",
+      self.upgrade_decision.getSimulationState())
+
+    self.upgrade_decision.plan()
+    self.upgrade_decision.start()
+    self.tic()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=software_release)
+
+    self.assertEqual("started",
+      self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_reviewRegistration_instance_tree(self):
+    self._makeTree()
+    self._addUpgradeLine(self.instance_tree)
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=self.instance_tree.getUrlString())
+
+    self.assertEqual("draft",
+      self.upgrade_decision.getSimulationState())
+
+    self.upgrade_decision.plan()
+    self.tic()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=self.instance_tree.getUrlString())
+
+    self.assertEqual("cancelled",
+      self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_reviewRegistration_instance_tree_confirmed(self):
+    self._makeTree()
+    self._addUpgradeLine(self.instance_tree)
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=self.instance_tree.getUrlString())
+
+    self.assertEqual("draft",
+      self.upgrade_decision.getSimulationState())
+
+    self.upgrade_decision.confirm()
+    self.tic()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=self.instance_tree.getUrlString())
+
+    self.assertEqual("cancelled",
+      self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_reviewRegistration_instance_tree_started(self):
+    self._makeTree()
+    self._addUpgradeLine(self.instance_tree)
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=self.instance_tree.getUrlString())
+
+    self.assertEqual("draft",
+      self.upgrade_decision.getSimulationState())
+
+    self.upgrade_decision.start()
+    self.tic()
+
+    self.upgrade_decision.reviewRegistration(
+      software_release_url=self.instance_tree.getUrlString())
+
+    self.assertEqual("started",
+      self.upgrade_decision.getSimulationState())
+
+  @simulate('InstanceTree_isUpgradePossible',
+            'software_release_url', 'return 1')
+  def test_upgrade_decision_requestUpgrade_instance_tree(self):
+    self._makeTree()
+    self._addUpgradeLine(self.instance_tree)
+    self.tic()
+   
+    slap_state = self.instance_tree.getSlapState()
+    
+    self.upgrade_decision.requestUpgrade()
+    self.assertNotEqual(self.software_release.getUrlString(),
+                        self.instance_tree.getUrlString())
+
+    self.upgrade_decision.confirm()
+    self.upgrade_decision.start()
+
+    # Check that url_string change, but slap state doesn't
+    self.assertNotEqual(self.software_release.getUrlString(),
+                        self.instance_tree.getUrlString())
+
+    self.upgrade_decision.requestUpgrade()
+    self.assertEqual(self.software_release.getUrlString(),
+                    self.instance_tree.getUrlString())
+
+
+    self.assertEqual(slap_state, self.instance_tree.getSlapState())
+    self.assertEqual('stopped', self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_requestUpgrade_instance_tree_no_software_release(self):
+    self._makeTree()
+    self.upgrade_decision.newContent(
+      portal_type="Upgrade Decision Line",
+      aggregate_value_list=[self.instance_tree]
+    )
+    
+    self.upgrade_decision.confirm()
+    self.upgrade_decision.start()
+    self.tic()
+
+    self.upgrade_decision.requestUpgrade()
+    self.assertEqual('started', self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_requestUpgrade_compute_node_no_software_release(self):
+    self.upgrade_decision.newContent(
+      portal_type="Upgrade Decision Line",
+      aggregate_value_list=[self.compute_node]
+    )
+    
+    self.upgrade_decision.confirm()
+    self.upgrade_decision.start()
+    self.tic()
+
+    self.upgrade_decision.requestUpgrade()
+    self.assertEqual('started', self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_requestUpgrade_only_software_release(self):
+    self.upgrade_decision.newContent(
+      portal_type="Upgrade Decision Line",
+      aggregate_value_list=[self.software_release]
+    )
+    
+    self.upgrade_decision.confirm()
+    self.upgrade_decision.start()
+    self.tic()
+
+    self.upgrade_decision.requestUpgrade()
+    self.assertEqual('started', self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_requestUpgrade_duplicated(self):
+    self._makeTree()
+    self.upgrade_decision.newContent(
+      portal_type="Upgrade Decision Line",
+      aggregate_value_list=[
+        self.software_release,
+        self.instance_tree,
+        self.compute_node]
+    )
+    
+    self.upgrade_decision.confirm()
+    self.upgrade_decision.start()
+    self.tic()
+
+    self.assertRaises(ValueError, self.upgrade_decision.requestUpgrade)
+    self.assertEqual('started', self.upgrade_decision.getSimulationState())
+
+  def test_upgrade_decision_requestUpgrade_compute_node(self):
+    self._addUpgradeLine(self.compute_node)
+    
+    self.upgrade_decision.confirm()
+    self.upgrade_decision.start()
+    self.tic()
+
+    self.upgrade_decision.requestUpgrade()
+    self.tic()
+
+    self.assertEqual('stopped', self.upgrade_decision.getSimulationState())
+    software_installation = self.compute_node.getAggregateRelatedValue(
+            portal_type='Software Installation')
+    self.assertEqual('start_requested', software_installation.getSlapState())
+    self.assertEqual(self.software_release.getUrlString(),
+      software_installation.getUrlString())
+    self.assertEqual('validated', software_installation.getValidationState())
+
+  @simulate('InstanceTree_isUpgradePossible',
+            'software_release_url', 'return 0')
+  def test_upgrade_decision_requestUpgrade_instance_tree_not_possible(self):
+    self._makeTree()
+    self._addUpgradeLine(self.instance_tree)
+
+    self.assertNotEqual(self.instance_tree.getUrlString(),
+      self.software_release.getUrlString())
+
+    slap_state = self.instance_tree.getSlapState()
+    self.upgrade_decision.confirm()
+    self.upgrade_decision.start()
+    self.tic()
+
+    self.upgrade_decision.requestUpgrade()
+    self.tic()
+
+    self.assertEqual('started', self.upgrade_decision.getSimulationState())
+    self.assertNotEqual(self.instance_tree.getUrlString(),
+      self.software_release.getUrlString())
+
+    self.assertEqual(slap_state,
+      self.instance_tree.getSlapState())
+
diff --git a/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudUpgradeSlapInterfaceWorkflow.xml b/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudUpgradeSlapInterfaceWorkflow.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4fcc72eb5465be15e7ca4a68cb8c48f19dc426cd
--- /dev/null
+++ b/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSCloudUpgradeSlapInterfaceWorkflow.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Test Component" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_recorded_property_dict</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>default_reference</string> </key>
+            <value> <string>testSlapOSCloudUpgradeSlapInterfaceWorkflow</string> </value>
+        </item>
+        <item>
+            <key> <string>default_source_reference</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>test.erp5.testSlapOSCloudUpgradeSlapInterfaceWorkflow</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Test Component</string> </value>
+        </item>
+        <item>
+            <key> <string>sid</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>text_content_error_message</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>text_content_warning_message</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>version</string> </key>
+            <value> <string>erp5</string> </value>
+        </item>
+        <item>
+            <key> <string>workflow_history</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary>
+                <item>
+                    <key> <string>component_validation_workflow</string> </key>
+                    <value>
+                      <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+                    </value>
+                </item>
+              </dictionary>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="4" aka="AAAAAAAAAAQ=">
+    <pickle>
+      <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_log</string> </key>
+            <value>
+              <list>
+                <dictionary>
+                  <item>
+                      <key> <string>action</string> </key>
+                      <value> <string>validate</string> </value>
+                  </item>
+                  <item>
+                      <key> <string>validation_state</string> </key>
+                      <value> <string>validated</string> </value>
+                  </item>
+                </dictionary>
+              </list>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSPDMCreateUpgradeDecisionSkins.py b/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSPDMCreateUpgradeDecisionSkins.py
index 2cd3d63492b94b30a3ae5e3f6a1e09dd65117813..485ef0fde94f3f35a0f52b6d0ab73283c7f2857c 100644
--- a/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSPDMCreateUpgradeDecisionSkins.py
+++ b/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSPDMCreateUpgradeDecisionSkins.py
@@ -284,11 +284,12 @@ class TestSlapOSPDMCreateUpgradeDecisionSkins(TestSlapOSPDMMixinSkins):
     self.assertNotEqual(up_decision, None)
     self.assertEqual(up_decision.getSimulationState(), 'planned')
     
-    self.assertEqual(up_decision.UpgradeDecision_getInstanceTree().\
+    self.assertEqual(up_decision.UpgradeDecision_getAggregateValue("Instance Tree").\
                       getReference(), instance_tree.getReference())
 
-    self.assertEqual(up_decision.UpgradeDecision_getSoftwareRelease().\
-                              getUrlString(), software_release2.getUrlString())
+    self.assertEqual(software_release2.getUrlString(),
+      up_decision.UpgradeDecision_getAggregateValue("Software Release").\
+                              getUrlString())
     
     self.tic()
     up_decision2 = instance_tree.InstanceTree_createUpgradeDecision()
@@ -331,7 +332,7 @@ class TestSlapOSPDMCreateUpgradeDecisionSkins(TestSlapOSPDMMixinSkins):
     up_decision2 = instance_tree.InstanceTree_createUpgradeDecision()
     self.assertEqual(up_decision2.getSimulationState(), 'planned')
     self.assertEqual(up_decision.getSimulationState(), 'cancelled')
-    release = up_decision2.UpgradeDecision_getSoftwareRelease()
+    release = up_decision2.UpgradeDecision_getAggregateValue("Software Release")
     self.assertEqual(release.getUrlString(),
                                 software_release3.getUrlString())
 
@@ -414,7 +415,7 @@ class TestSlapOSPDMCreateUpgradeDecisionSkins(TestSlapOSPDMMixinSkins):
     decision2 = instance_tree.InstanceTree_createUpgradeDecision()
     self.assertEqual(decision2.getSimulationState(), 'planned')
     self.assertEqual(up_decision.getSimulationState(), 'rejected')
-    release = decision2.UpgradeDecision_getSoftwareRelease()
+    release = decision2.UpgradeDecision_getAggregateValue("Software Release")
     self.assertEqual(release.getUrlString(),
                                 software_release3.getUrlString())
   
\ No newline at end of file
diff --git a/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSPDMSkins.py b/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSPDMSkins.py
index a03c1a399207c2fd76d6539ec9892edbede39ba5..ad418aad6338d18c5832848ee1922237eb3d2594 100644
--- a/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSPDMSkins.py
+++ b/master/bt5/slapos_pdm/TestTemplateItem/portal_components/test.erp5.testSlapOSPDMSkins.py
@@ -338,7 +338,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
     upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
     upgrade_decision_line.setAggregateValue(compute_node)
 
-    found_compute_node = upgrade_decision.UpgradeDecision_getComputeNode()
+    found_compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
     self.assertEqual(compute_node.getRelativeUrl(),
                       found_compute_node.getRelativeUrl())
 
@@ -351,7 +351,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
 
     upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
 
-    found_compute_node = upgrade_decision.UpgradeDecision_getComputeNode()
+    found_compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
     self.assertEqual(compute_node.getRelativeUrl(),
                       found_compute_node.getRelativeUrl())
 
@@ -365,13 +365,14 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
     upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
     upgrade_decision_line.setAggregateValue(compute_node)
 
-    self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getComputeNode)
+    self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getAggregateValue,
+      document_portal_type="Compute Node")
 
   def testUpgradeDecision_getComputeNode_O_compute_node(self):
     upgrade_decision = self._makeUpgradeDecision()
     self._makeUpgradeDecisionLine(upgrade_decision)
 
-    found_compute_node = upgrade_decision.UpgradeDecision_getComputeNode()
+    found_compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
     self.assertEqual(None, found_compute_node)
 
 
@@ -382,7 +383,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
     upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
     upgrade_decision_line.setAggregateValue(instance_tree)
 
-    found_instance_tree = upgrade_decision.UpgradeDecision_getInstanceTree()
+    found_instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
     self.assertEqual(instance_tree.getRelativeUrl(),
                       found_instance_tree.getRelativeUrl())
 
@@ -396,7 +397,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
 
     upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
 
-    found_instance_tree = upgrade_decision.UpgradeDecision_getInstanceTree()
+    found_instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
     self.assertEqual(instance_tree.getRelativeUrl(),
                       found_instance_tree.getRelativeUrl())
 
@@ -411,28 +412,29 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
     upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
     upgrade_decision_line.setAggregateValue(instance_tree)
 
-    self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getInstanceTree)
+    self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getAggregateValue,
+      document_portal_type="Instance Tree")
 
   def testUpgradeDecision_getInstanceTree_O_hosting(self):
     upgrade_decision = self._makeUpgradeDecision()
     self._makeUpgradeDecisionLine(upgrade_decision)
 
-    found_instance_tree = upgrade_decision.UpgradeDecision_getInstanceTree()
+    found_instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
     self.assertEqual(None, found_instance_tree)
 
      
-  def testUpgradeDecision_getSoftwareRelease(self):
+  def testUpgradeDecision_getAggregateValue_SoftwareRelease(self):
     software_release = self._makeSoftwareRelease()
     upgrade_decision = self._makeUpgradeDecision()
 
     upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
     upgrade_decision_line.setAggregateValue(software_release)
 
-    found_software_release = upgrade_decision.UpgradeDecision_getSoftwareRelease()
+    found_software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
     self.assertEqual(software_release.getRelativeUrl(),
                       found_software_release.getRelativeUrl())
 
-  def testUpgradeDecision_getSoftwareRelease_2_lines(self):
+  def testUpgradeDecision_getAggregateValue_SoftwareRelease_2_lines(self):
     software_release = self._makeSoftwareRelease()
     upgrade_decision = self._makeUpgradeDecision()
 
@@ -441,11 +443,11 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
 
     upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
 
-    found_software_release = upgrade_decision.UpgradeDecision_getSoftwareRelease()
+    found_software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
     self.assertEqual(software_release.getRelativeUrl(),
                       found_software_release.getRelativeUrl())
 
-  def testUpgradeDecision_getSoftwareRelease_2_sr(self):
+  def testUpgradeDecision_getAggregateValue_SoftwareRelease_2_sr(self):
     software_release = self._makeSoftwareRelease()
     upgrade_decision = self._makeUpgradeDecision()
 
@@ -455,212 +457,16 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
     upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
     upgrade_decision_line.setAggregateValue(software_release)
 
-    self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getSoftwareRelease)
+    self.assertRaises(ValueError, upgrade_decision.UpgradeDecision_getAggregateValue,
+      document_portal_type="Software Release")
 
-  def testUpgradeDecision_getSoftwareRelease_O_sr(self):
+  def testUpgradeDecision_getAggregateValue_SoftwareRelease_O_sr(self):
     upgrade_decision = self._makeUpgradeDecision()
     self._makeUpgradeDecisionLine(upgrade_decision)
 
-    found_software_release = upgrade_decision.UpgradeDecision_getSoftwareRelease()
+    found_software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
     self.assertEqual(None, found_software_release)
 
-  @simulate('InstanceTree_isUpgradePossible',
-            'software_release_url', 'return 1')
-  def testUpgradeDecision_upgradeInstanceTree(self):
-    person = self._makePerson()
-    instance_tree = self._makeInstanceTree()
-    instance_tree.edit(
-          destination_section_value = person.getRelativeUrl())
-
-    self._makeSoftwareInstance(instance_tree,
-                               instance_tree.getUrlString())
-   
-    software_release = self._makeSoftwareRelease()
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList(
-       [software_release, instance_tree])
-    self.tic()
-   
-    slap_state = instance_tree.getSlapState()
-    
-    self.assertFalse(upgrade_decision.UpgradeDecision_upgradeInstanceTree())
-    self.assertNotEqual(software_release.getUrlString(),
-                     instance_tree.getUrlString())
-
-    upgrade_decision.confirm()
-    upgrade_decision.start()
-
-    # Check that url_string change, but slap state doesn't
-    self.assertNotEqual(software_release.getUrlString(),
-                     instance_tree.getUrlString())
-
-    self.assertTrue(upgrade_decision.UpgradeDecision_upgradeInstanceTree())
-    self.assertEqual(software_release.getUrlString(),
-                     instance_tree.getUrlString())
-
-    self.assertEqual(slap_state, instance_tree.getSlapState())
-    self.assertEqual('stopped', upgrade_decision.getSimulationState())
-
-  @simulate('InstanceTree_isUpgradePossible',
-            'software_release_url', 'return 1')
-  def testUpgradeDecision_processUpgradeeInstanceTree(self):
-    person = self._makePerson()
-    instance_tree = self._makeInstanceTree()
-    instance_tree.edit(
-          destination_section_value = person.getRelativeUrl())
-
-    self._makeSoftwareInstance(instance_tree,
-                               instance_tree.getUrlString())
-   
-    software_release = self._makeSoftwareRelease()
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList(
-       [software_release, instance_tree])
-    self.tic()
-   
-    slap_state = instance_tree.getSlapState()
-    
-    self.assertFalse(upgrade_decision.UpgradeDecision_processUpgrade())
-    self.assertNotEqual(software_release.getUrlString(),
-                     instance_tree.getUrlString())
-
-    upgrade_decision.confirm()
-    upgrade_decision.start()
-
-    # Check that url_string change, but slap state doesn't
-    self.assertNotEqual(software_release.getUrlString(),
-                     instance_tree.getUrlString())
-
-    self.assertTrue(upgrade_decision.UpgradeDecision_processUpgrade())
-    self.assertEqual(software_release.getUrlString(),
-                     instance_tree.getUrlString())
-
-    self.assertEqual(slap_state, instance_tree.getSlapState())
-    self.assertEqual('stopped', upgrade_decision.getSimulationState())
-
-
-  def testUpgradeDecision_upgradeInstanceTree_no_software_release(self):
-
-    person = self._makePerson()
-    instance_tree = self._makeInstanceTree()
-    instance_tree.edit(
-          destination_section_value = person.getRelativeUrl())
-
-    self._makeSoftwareInstance(instance_tree,
-                               instance_tree.getUrlString())
-   
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList([instance_tree])
-    self.tic()
-   
-    upgrade_decision.confirm()
-    upgrade_decision.start()
-
-    self.assertFalse(upgrade_decision.UpgradeDecision_upgradeInstanceTree())
-    self.assertEqual('started', upgrade_decision.getSimulationState())
-
-  def testUpgradeDecision_upgradeInstanceTree_no_hosting_subscripion(self):
-
-    software_release = self._makeSoftwareRelease()
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList([software_release])
-    self.tic()
-    
-    upgrade_decision.confirm()
-    upgrade_decision.start()
-
-    self.assertFalse(upgrade_decision.UpgradeDecision_upgradeInstanceTree())
-    self.assertEqual('started', upgrade_decision.getSimulationState())
-    
-  def testUpgradeDecision_upgradeComputeNode_no_software_release(self):
-
-    person = self._makePerson()
-    compute_node, _ = self._makeComputeNode(owner=person)
-
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList([compute_node])
-    self.tic()
-   
-    upgrade_decision.confirm()
-    upgrade_decision.start()
-
-    self.assertFalse(upgrade_decision.UpgradeDecision_upgradeComputeNode())
-    self.assertEqual('started', upgrade_decision.getSimulationState())
-
-
-  def testUpgradeDecision_upgradeComputeNode_no_hosting_subscripion(self):
-
-    software_release = self._makeSoftwareRelease()
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList([software_release])
-    self.tic()
-    
-    upgrade_decision.confirm()
-    upgrade_decision.start()
-
-    self.assertFalse(upgrade_decision.UpgradeDecision_upgradeComputeNode())
-    self.assertEqual('started', upgrade_decision.getSimulationState())
-    
-  def testUpgradeDecision_upgradeComputeNode(self):
-    self._makePerson()
-    compute_node, _ = self._makeComputeNode()
-    software_release = self._makeSoftwareRelease()
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList([software_release, compute_node])
-    url = software_release.getUrlString()
-    
-    self.tic()
-
-    self.assertFalse(upgrade_decision.UpgradeDecision_upgradeComputeNode())
-
-    upgrade_decision.confirm()
-    upgrade_decision.start()
-
-    self.assertTrue(upgrade_decision.UpgradeDecision_upgradeComputeNode())
-    self.tic()
-    
-    software_installation = compute_node.getAggregateRelatedValue(
-            portal_type='Software Installation')
-    self.assertEqual('start_requested', software_installation.getSlapState())
-    self.assertEqual(url, software_installation.getUrlString())
-    self.assertEqual('validated', software_installation.getValidationState())
-    self.assertEqual('stopped', upgrade_decision.getSimulationState())
-
-
-  def testUpgradeDecision_processUpgradeComputeNode(self):
-    self._makePerson()
-    compute_node, _ = self._makeComputeNode()
-    software_release = self._makeSoftwareRelease()
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList([software_release, compute_node])
-    url = software_release.getUrlString()
-    
-    self.tic()
-
-    self.assertFalse(upgrade_decision.UpgradeDecision_processUpgrade())
-
-    upgrade_decision.confirm()
-    upgrade_decision.start()
-
-    self.assertTrue(upgrade_decision.UpgradeDecision_processUpgrade())
-    self.tic()
-    
-    software_installation = compute_node.getAggregateRelatedValue(
-            portal_type='Software Installation')
-    self.assertEqual('start_requested', software_installation.getSlapState())
-    self.assertEqual(url, software_installation.getUrlString())
-    self.assertEqual('validated', software_installation.getValidationState())
-    self.assertEqual('stopped', upgrade_decision.getSimulationState())
-
-
   def testSoftwareRelease_createUpgradeDecision_compute_node(self):
     person = self._makePerson()
     compute_node, _ = self._makeComputeNode(owner=person)
@@ -893,54 +699,6 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
     self.assertEqual(in_progress, None)
   
   
-  def testUpgradeDecision_tryToCancel(self):
-    compute_node, _ = self._makeComputeNode()
-    software_release = self._makeSoftwareRelease()
-    software_release2 = self._makeSoftwareRelease()
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList([software_release, compute_node])
-    upgrade_decision.confirm()
-    
-    upgrade_decision2 = self._makeUpgradeDecision()
-    upgrade_decision_line2 = self._makeUpgradeDecisionLine(upgrade_decision2)
-    upgrade_decision_line2.setAggregateValueList([software_release, compute_node])
-    upgrade_decision2.confirm()
-    upgrade_decision2.start()
-    
-    url = software_release.getUrlString()
-    url2 = software_release2.getUrlString()
-    
-    # Cancel is not possible with the same url_string
-    self.assertEqual(upgrade_decision.UpgradeDecision_tryToCancel(url), False)
-    self.assertEqual(upgrade_decision.UpgradeDecision_tryToCancel(url2), True)
-    self.assertEqual(upgrade_decision.getSimulationState(), 'cancelled')
-    
-    # Cancel is no longer possible
-    self.assertEqual(upgrade_decision2.UpgradeDecision_tryToCancel(url), False)
-    self.assertEqual(upgrade_decision2.UpgradeDecision_tryToCancel(url2), False)
-    self.assertEqual(upgrade_decision2.getSimulationState(), 'started')
-
-  def testUpgradeDecision_tryToCancel_withRejected(self):
-    compute_node, _ = self._makeComputeNode()
-    software_release = self._makeSoftwareRelease()
-    software_release2 = self._makeSoftwareRelease()
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList([software_release, compute_node])
-    upgrade_decision.confirm()
-    upgrade_decision.reject()
-    
-    url = software_release.getUrlString()
-    url2 = software_release2.getUrlString()
-    
-    # Try to cancel rejected UD with the same sr will return False
-    self.assertEqual(upgrade_decision.UpgradeDecision_tryToCancel(url), False)
-    self.assertEqual(upgrade_decision.getSimulationState(), 'rejected')
-    # Try to cancel rejected UD will return True with url2
-    self.assertEqual(upgrade_decision.UpgradeDecision_tryToCancel(url2), True)
-    self.assertEqual(upgrade_decision.getSimulationState(), 'rejected')
-    
   def testComputeNode_checkAndCreateUpgradeDecision_auto(self):
     person = self._makePerson()
     compute_node, _ = self._makeComputeNode(owner=person,
@@ -966,10 +724,10 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
     self.assertEqual(len(upgrade_decision), 1)
     self.assertEqual(upgrade_decision[0].getSimulationState(), 'started')
     
-    compute_node_aggregate = upgrade_decision[0].UpgradeDecision_getComputeNode()
-    self.assertEqual(compute_node_aggregate.getReference(),
-                      compute_node.getReference())
-    release = upgrade_decision[0].UpgradeDecision_getSoftwareRelease()
+    compute_node_aggregate = upgrade_decision[0].UpgradeDecision_getAggregateValue("Compute Node")
+    self.assertEqual(compute_node_aggregate,
+                      compute_node)
+    release = upgrade_decision[0].UpgradeDecision_getAggregateValue("Software Release")
     self.assertEqual(release.getUrlString(),
                                 software_release2.getUrlString())
     self.tic()
@@ -1001,7 +759,7 @@ class TestSlapOSPDMSkins(TestSlapOSPDMMixinSkins):
     
     self.assertEqual(upgrade_decision.getSimulationState(), 'cancelled')
     self.assertEqual(upgrade_decision2.getSimulationState(), 'planned')
-    release = upgrade_decision2.UpgradeDecision_getSoftwareRelease()
+    release = upgrade_decision2.UpgradeDecision_getAggregateValue("Software Release")
     self.assertEqual(release.getUrlString(),
                                 software_release3.getUrlString())
   
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5131e5492d9817b4d6bd539cf1dbbc9186ae8344
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>_count</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>_mt_index</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>_tree</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>source/portal_workflow/upgrade_slap_interface_workflow/state_draft</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>comment</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>default_reference</string> </key>
+            <value> <string>person_slap_interface_workflow</string> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>upgrade_slap_interface_workflow</string> </value>
+        </item>
+        <item>
+            <key> <string>language</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>manager_bypass</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow</string> </value>
+        </item>
+        <item>
+            <key> <string>state_variable</string> </key>
+            <value> <string>slap_state</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Upgrade Slap Interface Workflow</string> </value>
+        </item>
+        <item>
+            <key> <string>workflow_managed_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="Length" module="BTrees.Length"/>
+    </pickle>
+    <pickle> <int>0</int> </pickle>
+  </record>
+  <record id="3" aka="AAAAAAAAAAM=">
+    <pickle>
+      <global name="OOBTree" module="BTrees.OOBTree"/>
+    </pickle>
+    <pickle>
+      <none/>
+    </pickle>
+  </record>
+  <record id="4" aka="AAAAAAAAAAQ=">
+    <pickle>
+      <global name="OOBTree" module="BTrees.OOBTree"/>
+    </pickle>
+    <pickle>
+      <none/>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_approveRegistration.py b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_approveRegistration.py
new file mode 100644
index 0000000000000000000000000000000000000000..ef4802639e5b3b1be057528fd77674d3914b2676
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_approveRegistration.py
@@ -0,0 +1,38 @@
+upgrade_decision = state_change["object"]
+from DateTime import DateTime
+
+portal = upgrade_decision.getPortalObject()
+document = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
+if document is None:
+  document = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
+
+if document is None:
+  raise ValueError("No Compute Node or Instance Tree associated to upgrade.")
+
+# Get required arguments
+kwargs = state_change.kwargs
+
+# Required args
+# Raise TypeError if all parameters are not provided
+try:
+  upgrade_scope = kwargs['upgrade_scope']
+except KeyError:
+  raise TypeError("UpgradeDecision_approveRegistration takes exactly 1 arguments")
+
+tag = "%s_requestUpgradeDecisionCreation_inProgress" % document.getUid()
+activate_kw = {'tag': tag}
+if portal.portal_activities.countMessageWithTag(tag) > 0:
+  # nothing to do
+  return
+
+with upgrade_decision.defaultActivateParameterDict(activate_kw):
+  if upgrade_decision.getSimulationState() == "draft":
+    upgrade_decision.plan()
+
+  upgrade_decision.setStartDate(DateTime())
+  if upgrade_scope == "auto":
+    if upgrade_decision.getSimulationState() == "planned":
+      upgrade_decision.start()
+
+# Prevent concurrent transaction to create 2 upgrade decision for the same instance_tree
+document.serialize()
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_approveRegistration.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_approveRegistration.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dc620eec35950baafdb840711b103928caf4e45d
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_approveRegistration.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Script" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>state_change</string> </value>
+        </item>
+        <item>
+            <key> <string>_proxy_roles</string> </key>
+            <value>
+              <tuple>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>script_UpgradeDecision_approveRegistration</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Script</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>UpgradeDecision_approveRegistration</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency.py b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency.py
new file mode 100644
index 0000000000000000000000000000000000000000..53d0e5dfe3609b88e40bbd9406fd08ef0b5643fe
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency.py
@@ -0,0 +1,2 @@
+upgrade_decision = state_change['object']
+upgrade_decision.Base_checkConsistency()
diff --git a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_WebMessage_stopAndReopenTicket.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency.xml
similarity index 89%
rename from master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_WebMessage_stopAndReopenTicket.xml
rename to master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency.xml
index 9c04e3ee0f8cf85a40a8996571a0186f9a881d44..8f0d9fbf4e41118ac2cfdc6eee87bd5cb066a80e 100644
--- a/master/bt5/slapos_erp5/WorkflowTemplateItem/portal_workflow/slapos_erp5_interaction_workflow/script_WebMessage_stopAndReopenTicket.xml
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency.xml
@@ -50,19 +50,17 @@
         </item>
         <item>
             <key> <string>_params</string> </key>
-            <value> <string>state_object</string> </value>
+            <value> <string>state_change</string> </value>
         </item>
         <item>
-            <key> <string>_proxy_roles</string> </key>
+            <key> <string>description</string> </key>
             <value>
-              <tuple>
-                <string>Assignor</string>
-              </tuple>
+              <none/>
             </value>
         </item>
         <item>
             <key> <string>id</string> </key>
-            <value> <string>script_WebMessage_stopAndReopenTicket</string> </value>
+            <value> <string>script_UpgradeDecision_checkConsistency</string> </value>
         </item>
         <item>
             <key> <string>portal_type</string> </key>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_notify.py b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_notify.py
new file mode 100644
index 0000000000000000000000000000000000000000..f0234486cdfca4dcad044c7c2929f99a0bf1c8b8
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_notify.py
@@ -0,0 +1,53 @@
+upgrade_decision = state_change["object"]
+from DateTime import DateTime
+
+portal = context.getPortalObject()
+
+# Get required arguments
+kwargs = state_change.kwargs
+
+# Required args
+# Raise TypeError if all parameters are not provided
+try:
+  message_title = kwargs['message_title']
+  message = kwargs['message']
+  destination_relative_url = kwargs['destination_relative_url']
+except KeyError:
+  raise TypeError("UpgradeDecision_requestEvent takes exactly 3 arguments")
+
+resource = portal.service_module.slapos_crm_information.getRelativeUrl()
+# create Web message if needed for this ticket
+last_event = portal.portal_catalog.getResultValue(
+             title=message_title,
+             follow_up_uid=upgrade_decision.getUid(),
+             sort_on=[('delivery.start_date', 'DESC')],
+)
+if last_event:
+  # User has already been notified for this problem.
+  return last_event
+
+transactional_event = context.REQUEST.get("upgrade_decision_notified_item", None)
+
+if transactional_event is not None:
+  if (transactional_event.getFollowUpUid() == upgrade_decision.getUid()) and \
+    (transactional_event.getTitle() == message_title):
+    return transactional_event
+
+template = portal.restrictedTraverse(
+        portal.portal_preferences.getPreferredWebMessageTemplate())
+
+event = template.Base_createCloneDocument(batch_mode=1)
+event.edit(
+  title=message_title,
+  text_content=message,
+  start_date = DateTime(),
+  resource = resource,
+  source=upgrade_decision.getSource(),
+  destination=destination_relative_url,
+  follow_up=upgrade_decision.getRelativeUrl(),
+)
+event.stop()
+event.deliver()
+
+upgrade_decision.serialize()
+upgrade_decision.REQUEST.set("upgrade_decision_notified_item", event)
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_notify.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_notify.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ff74a6b365baa23d136de50bca3bf47b499645b2
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_notify.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Script" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>state_change</string> </value>
+        </item>
+        <item>
+            <key> <string>_proxy_roles</string> </key>
+            <value>
+              <tuple>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>script_UpgradeDecision_notify</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Script</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>UpgradeDecision_notify</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_requestUpgrade.py b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_requestUpgrade.py
new file mode 100644
index 0000000000000000000000000000000000000000..a5e98a52f55fc672362da5444f0aecd619afdbba
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_requestUpgrade.py
@@ -0,0 +1,56 @@
+upgrade_decision = state_change["object"]
+from DateTime import DateTime
+
+if upgrade_decision.getSimulationState() != 'started':
+  # Update Decision is not on started state, Upgrade is not possible!
+  return
+
+instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
+software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
+compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
+
+if software_release is None:
+  return 
+
+if compute_node is None and instance_tree is None:
+  return
+
+if compute_node is not None and instance_tree is not None:
+  raise ValueError("Something is wrong, you cannot upgrade Compute Node and Instance Tree on the same decision.")
+
+software_release_url = software_release.getUrlString()
+
+if compute_node is not None:
+  compute_node.requestSoftwareRelease(
+   software_release_url=software_release_url,
+   state="available")
+
+  upgrade_decision.stop(comment="Upgrade Processed for the Compute Node!")
+  return
+
+# Test if the Software is available at the ComputeNode.
+if not instance_tree.InstanceTree_isUpgradePossible(
+  software_release_url=software_release_url):
+  return
+
+status = instance_tree.getSlapState()
+if status == "start_requested":
+  state = "started"
+elif status == "stop_requested":
+  state = "stopped"
+elif status == "destroy_requested":
+  state = "destroyed"
+
+person = instance_tree.getDestinationSectionValue(portal_type="Person")
+person.requestSoftwareInstance(
+  state=state,
+  software_release=software_release_url,
+  software_title=instance_tree.getTitle(),
+  software_type=instance_tree.getSourceReference(),
+  instance_xml=instance_tree.getTextContent(),
+  sla_xml=instance_tree.getSlaXml(),
+  shared=instance_tree.isRootSlave()
+)
+
+upgrade_decision.stop(
+  comment="Upgrade Processed for the Instance Tree!")
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_requestUpgrade.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_requestUpgrade.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f88c816f726bb5caaa83250f8676f4736ae71fed
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_requestUpgrade.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Script" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>state_change</string> </value>
+        </item>
+        <item>
+            <key> <string>_proxy_roles</string> </key>
+            <value>
+              <tuple>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>script_UpgradeDecision_requestUpgrade</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Script</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>UpgradeDecision_requestUpgrade</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewRegistration.py b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewRegistration.py
new file mode 100644
index 0000000000000000000000000000000000000000..c66e2041c851a14a5ed85e7d94556fbb7d2bd91e
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewRegistration.py
@@ -0,0 +1,37 @@
+upgrade_decision = state_change["object"]
+from DateTime import DateTime
+
+cancellable_state_list = ['confirmed', 'planned']
+require_state_list = ['rejected', 'confirmed', 'planned']
+simulation_state = upgrade_decision.getSimulationState()
+
+# Get required arguments
+kwargs = state_change.kwargs
+
+# Required args
+# Raise TypeError if all parameters are not provided
+try:
+  software_release_url = kwargs['software_release_url']
+except KeyError:
+  raise TypeError("UpgradeDecision_reviewRegistration takes exactly 1 arguments")
+
+if simulation_state in require_state_list:
+  current_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
+  if not current_release:
+    # This upgrade decision is not valid
+    return
+
+  instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
+  if instance_tree is not None:
+    current_instance_tree_release = instance_tree.getUrlString()
+    if current_instance_tree_release == software_release_url:
+      if simulation_state in cancellable_state_list:
+        upgrade_decision.cancel(comment="Instance tree is already upgraded.")
+      return
+
+  if current_release.getUrlString() == software_release_url:
+    # Cannot cancel because the software releases are the same
+    return False
+
+  if simulation_state in cancellable_state_list:
+    upgrade_decision.cancel()
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getSoftwareRelease.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewRegistration.xml
similarity index 70%
rename from master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getSoftwareRelease.xml
rename to master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewRegistration.xml
index bd836b2306b424617586ac302ad3e31d42269529..de47b7d637cc54649a1eefd5895c51ee243bc285 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_getSoftwareRelease.xml
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewRegistration.xml
@@ -2,7 +2,7 @@
 <ZopeData>
   <record id="1" aka="AAAAAAAAAAE=">
     <pickle>
-      <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
+      <global name="Workflow Script" module="erp5.portal_type"/>
     </pickle>
     <pickle>
       <dictionary>
@@ -50,11 +50,33 @@
         </item>
         <item>
             <key> <string>_params</string> </key>
-            <value> <string></string> </value>
+            <value> <string>state_change</string> </value>
+        </item>
+        <item>
+            <key> <string>_proxy_roles</string> </key>
+            <value>
+              <tuple>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
         </item>
         <item>
             <key> <string>id</string> </key>
-            <value> <string>UpgradeDecision_getSoftwareRelease</string> </value>
+            <value> <string>script_UpgradeDecision_reviewRegistration</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Script</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>UpgradeDecision_reviewRegistration</string> </value>
         </item>
       </dictionary>
     </pickle>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewUpgrade.py b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewUpgrade.py
new file mode 100644
index 0000000000000000000000000000000000000000..d2d707bd02d7bf7caf179a7055ee6ee849bd1f32
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewUpgrade.py
@@ -0,0 +1,43 @@
+upgrade_decision = state_change["object"]
+from DateTime import DateTime
+
+portal = upgrade_decision.getPortalObject()
+
+instance_tree = upgrade_decision.UpgradeDecision_getAggregateValue("Instance Tree")
+software_release = upgrade_decision.UpgradeDecision_getAggregateValue("Software Release")
+
+if upgrade_decision.getSimulationState() == "cancelled":
+  return
+
+if software_release.getValidationState() == "archived":
+  upgrade_decision.cancel(comment="Software Release is archived.")
+  return
+
+if instance_tree is not None:
+  if instance_tree.getUpgradeScope() in ['never', 'disabled']:
+    upgrade_decision.cancel("Upgrade scope was disabled on the related Instance Tree")
+
+  elif instance_tree.getSlapState() == "destroy_requested":
+    upgrade_decision.cancel(comment="Instance Tree is destroyed.")
+
+  elif instance_tree.getUrlString() == software_release.getUrlString():
+    upgrade_decision.cancel(comment="Instance tree is already upgraded.")
+
+  return
+
+compute_node = upgrade_decision.UpgradeDecision_getAggregateValue("Compute Node")
+if compute_node is not None:
+  if compute_node.getUpgradeScope() in ['never', 'disabled']:
+    upgrade_decision.cancel("Upgrade scope was disabled on the related Instance Tree")
+    return
+
+  elif compute_node.getAllocationScope() in ["closed/forever", "closed/termination"]:
+    upgrade_decision.cancel(comment="Compute Node is closed.")
+    return
+
+  already_deployed = len(portal.portal_catalog(limit=1,
+    portal_type="Compute Partition",
+    parent_reference=compute_node.getReference(),
+    software_release_url=software_release.getUrlString()))
+  if already_deployed:
+    upgrade_decision.cancel(comment="Compute Node already has the software release")
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewUpgrade.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewUpgrade.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3f0921561769b5b789bd8e214ab2f56dfcf0b1c6
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewUpgrade.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Script" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>Script_magic</string> </key>
+            <value> <int>3</int> </value>
+        </item>
+        <item>
+            <key> <string>_bind_names</string> </key>
+            <value>
+              <object>
+                <klass>
+                  <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
+                </klass>
+                <tuple/>
+                <state>
+                  <dictionary>
+                    <item>
+                        <key> <string>_asgns</string> </key>
+                        <value>
+                          <dictionary>
+                            <item>
+                                <key> <string>name_container</string> </key>
+                                <value> <string>container</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_context</string> </key>
+                                <value> <string>context</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_m_self</string> </key>
+                                <value> <string>script</string> </value>
+                            </item>
+                            <item>
+                                <key> <string>name_subpath</string> </key>
+                                <value> <string>traverse_subpath</string> </value>
+                            </item>
+                          </dictionary>
+                        </value>
+                    </item>
+                  </dictionary>
+                </state>
+              </object>
+            </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>state_change</string> </value>
+        </item>
+        <item>
+            <key> <string>_proxy_roles</string> </key>
+            <value>
+              <tuple>
+                <string>Manager</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>script_UpgradeDecision_reviewUpgrade</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Script</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>UpgradeDecision_reviewUpgrade</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/state_draft.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/state_draft.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2c9384eb0c3dada27731335ebcce830e848f9e8c
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/state_draft.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow State" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>acquire_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_approve_registration</string>
+                <string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_notify</string>
+                <string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_request_upgrade</string>
+                <string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_review_registration</string>
+                <string>destination/portal_workflow/upgrade_slap_interface_workflow/transition_review_upgrade</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>comment</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>state_draft</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow State</string> </value>
+        </item>
+        <item>
+            <key> <string>state_permission_role_list_dict</string> </key>
+            <value>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
+            </value>
+        </item>
+        <item>
+            <key> <string>state_type</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Draft</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+  <record id="2" aka="AAAAAAAAAAI=">
+    <pickle>
+      <global name="PersistentMapping" module="Persistence.mapping"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>data</string> </key>
+            <value>
+              <dictionary/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_approve_registration.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_approve_registration.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e09d397250b9a0cb6f9f7368bdf0f19ad95dd4f9
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_approve_registration.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Transition" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>action</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>action_name</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>action_type/workflow</string>
+                <string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
+                <string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_approveRegistration</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>guard_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>icon</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>transition_approve_registration</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Transition</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Approve Registration</string> </value>
+        </item>
+        <item>
+            <key> <string>trigger_type</string> </key>
+            <value> <int>2</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_notify.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_notify.xml
new file mode 100644
index 0000000000000000000000000000000000000000..14e8497efc32c11f667913f38c782bb728084484
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_notify.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Transition" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>action</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>action_name</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>action_type/workflow</string>
+                <string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
+                <string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_notify</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Create an event for the Upgrade Decision</string> </value>
+        </item>
+        <item>
+            <key> <string>guard_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>icon</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>transition_notify</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Transition</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Notify</string> </value>
+        </item>
+        <item>
+            <key> <string>trigger_type</string> </key>
+            <value> <int>2</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_request_upgrade.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_request_upgrade.xml
new file mode 100644
index 0000000000000000000000000000000000000000..73522c837aa7ac44c0eff4b7e7534db3efa12e1c
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_request_upgrade.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Transition" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>action</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>action_name</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>action_type/workflow</string>
+                <string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
+                <string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_requestUpgrade</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Perform the Upgrade</string> </value>
+        </item>
+        <item>
+            <key> <string>guard_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>icon</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>transition_request_upgrade</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Transition</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Request Upgrade</string> </value>
+        </item>
+        <item>
+            <key> <string>trigger_type</string> </key>
+            <value> <int>2</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_review_registration.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_review_registration.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d869a966493c27fb7b93f06d831953f5bda58d1a
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_review_registration.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Transition" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>action</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>action_name</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>action_type/workflow</string>
+                <string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
+                <string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewRegistration</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Cancel if the current upgrade isn\'t valid anymore. </string> </value>
+        </item>
+        <item>
+            <key> <string>guard_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>icon</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>transition_review_registration</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Transition</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Review Registration</string> </value>
+        </item>
+        <item>
+            <key> <string>trigger_type</string> </key>
+            <value> <int>2</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_review_upgrade.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_review_upgrade.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a0ac111b524f11c6784e258a2bda54b6e36d83e1
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/transition_review_upgrade.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Transition" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>action</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>action_name</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>categories</string> </key>
+            <value>
+              <tuple>
+                <string>action_type/workflow</string>
+                <string>before_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_checkConsistency</string>
+                <string>after_script/portal_workflow/upgrade_slap_interface_workflow/script_UpgradeDecision_reviewUpgrade</string>
+              </tuple>
+            </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Review if the upgrade still applicable</string> </value>
+        </item>
+        <item>
+            <key> <string>guard_permission</string> </key>
+            <value>
+              <tuple/>
+            </value>
+        </item>
+        <item>
+            <key> <string>icon</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>transition_review_upgrade</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Transition</string> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value> <string>Review Upgrade</string> </value>
+        </item>
+        <item>
+            <key> <string>trigger_type</string> </key>
+            <value> <int>2</int> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_action.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_action.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ba0016f3d69b0273369ad6802eb18c8313ea614e
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_action.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>The last transition</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_action</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>variable_default_expression</string> </key>
+            <value> <string>transition/getReference|nothing</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_actor.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_actor.xml
new file mode 100644
index 0000000000000000000000000000000000000000..028d9db6a333f0cda3309140372c927214decf31
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_actor.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>The name of the user who performed the last transition</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_actor</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>variable_default_expression</string> </key>
+            <value> <string>user/getUserName</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_comment.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_comment.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b41853beaf1d6aea72c0e4eb3cbdcaa4969ebfc8
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_comment.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Comments about the last transition</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_comment</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>variable_default_expression</string> </key>
+            <value> <string>python:state_change.kwargs.get(\'comment\', \'\')</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_error_message.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_error_message.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2b761c20e6aaa4fc8708edf2ce7109154b8427d5
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_error_message.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Error message if validation failed</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_error_message</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_history.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_history.xml
new file mode 100644
index 0000000000000000000000000000000000000000..95a08300b717c82a90e3a2906285f051479b38a2
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_history.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Provides access to workflow history</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_history</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>variable_default_expression</string> </key>
+            <value> <string>state_change/getHistory</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_portal_type.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_portal_type.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3609f65ad5051b7649d2b055bca6dd2d0fd70551
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_portal_type.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>portal type (use as filter for worklists)</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_portal_type</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_time.xml b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_time.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4e488bde05a81a4b25e955b22ea25ba4e6c56d9c
--- /dev/null
+++ b/master/bt5/slapos_pdm/WorkflowTemplateItem/portal_workflow/upgrade_slap_interface_workflow/variable_time.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<ZopeData>
+  <record id="1" aka="AAAAAAAAAAE=">
+    <pickle>
+      <global name="Workflow Variable" module="erp5.portal_type"/>
+    </pickle>
+    <pickle>
+      <dictionary>
+        <item>
+            <key> <string>automatic_update</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>description</string> </key>
+            <value> <string>Time of the last transition</string> </value>
+        </item>
+        <item>
+            <key> <string>for_catalog</string> </key>
+            <value> <int>0</int> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>variable_time</string> </value>
+        </item>
+        <item>
+            <key> <string>portal_type</string> </key>
+            <value> <string>Workflow Variable</string> </value>
+        </item>
+        <item>
+            <key> <string>status_included</string> </key>
+            <value> <int>1</int> </value>
+        </item>
+        <item>
+            <key> <string>title</string> </key>
+            <value>
+              <none/>
+            </value>
+        </item>
+        <item>
+            <key> <string>variable_default_expression</string> </key>
+            <value> <string>state_change/getDateTime</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/bt/template_portal_type_workflow_chain_list b/master/bt5/slapos_pdm/bt/template_portal_type_workflow_chain_list
index b1703064a6a0ee5711d5a066e5e65902a7ab91a6..66f588a3bb6cd8812f3e24d787bf060f10699797 100644
--- a/master/bt5/slapos_pdm/bt/template_portal_type_workflow_chain_list
+++ b/master/bt5/slapos_pdm/bt/template_portal_type_workflow_chain_list
@@ -2,4 +2,5 @@ Software Product | -validation_workflow
 Software Product | commerce_validation_workflow
 Upgrade Decision | edit_workflow
 Upgrade Decision | ticket_interaction_workflow
-Upgrade Decision | upgrade_decision_workflow
\ No newline at end of file
+Upgrade Decision | upgrade_decision_workflow
+Upgrade Decision | upgrade_slap_interface_workflow
\ No newline at end of file
diff --git a/master/bt5/slapos_pdm/bt/template_test_id_list b/master/bt5/slapos_pdm/bt/template_test_id_list
index 281d27b1f5ee7f4237a247d03a2fd5c083962356..51ffc9351ebac8cec437ea51ba49cc2f74689349 100644
--- a/master/bt5/slapos_pdm/bt/template_test_id_list
+++ b/master/bt5/slapos_pdm/bt/template_test_id_list
@@ -1,4 +1,5 @@
 test.erp5.testSlapOSPDMAlarm
 test.erp5.testSlapOSPDMSkins
 test.erp5.testSlapOSPDMDestroySoftwareInstallationWithArchivedSoftwareReleaseAlarm
-test.erp5.testSlapOSPDMCreateUpgradeDecisionSkins
\ No newline at end of file
+test.erp5.testSlapOSPDMCreateUpgradeDecisionSkins
+test.erp5.testSlapOSCloudUpgradeSlapInterfaceWorkflow
\ No newline at end of file
diff --git a/master/bt5/slapos_pdm/bt/template_workflow_id_list b/master/bt5/slapos_pdm/bt/template_workflow_id_list
index 00d4175090e13c024d9499553849be03b8822ef7..96d381081af2784596e8bbe19e6b2b4a142fa0a3 100644
--- a/master/bt5/slapos_pdm/bt/template_workflow_id_list
+++ b/master/bt5/slapos_pdm/bt/template_workflow_id_list
@@ -1 +1,2 @@
-upgrade_decision_workflow
\ No newline at end of file
+upgrade_decision_workflow
+upgrade_slap_interface_workflow
\ No newline at end of file