diff --git a/master/bt5/slapos_slap_tool/ExtensionTemplateItem/portal_components/extension.erp5.SlapOSSlapTool.py b/master/bt5/slapos_slap_tool/ExtensionTemplateItem/portal_components/extension.erp5.SlapOSSlapTool.py
index d3df777a7667f984ce1aa1e0ffc90f4f9d2b02e0..600afc06edb5e213c0b4c8e0b4f4ae8ff5a178b3 100644
--- a/master/bt5/slapos_slap_tool/ExtensionTemplateItem/portal_components/extension.erp5.SlapOSSlapTool.py
+++ b/master/bt5/slapos_slap_tool/ExtensionTemplateItem/portal_components/extension.erp5.SlapOSSlapTool.py
@@ -16,7 +16,9 @@ def getComputeNodeReferenceAndUserId(item):
     if partition is not None:
       compute_node = partition.getParentValue()
 
-  if compute_node is not None and compute_node.getValidationState() == 'validated':
+  if (compute_node is not None) and \
+    (compute_node.getPortalType() == 'Compute Node') and \
+    (compute_node.getValidationState() == 'validated'):
     return compute_node, compute_node.getReference(), compute_node.getUserId()
   return None, None, None
 
diff --git a/master/bt5/slapos_slap_tool/ExtensionTemplateItem/portal_components/extension.erp5.SlapOSSlapTool.xml b/master/bt5/slapos_slap_tool/ExtensionTemplateItem/portal_components/extension.erp5.SlapOSSlapTool.xml
index e2809f6ea507f60dee7aebea084b58259f5ec538..cc099b16061d8edcfeff081f5ab01019a4d459d4 100644
--- a/master/bt5/slapos_slap_tool/ExtensionTemplateItem/portal_components/extension.erp5.SlapOSSlapTool.xml
+++ b/master/bt5/slapos_slap_tool/ExtensionTemplateItem/portal_components/extension.erp5.SlapOSSlapTool.xml
@@ -6,12 +6,6 @@
     </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>SlapOSSlapTool</string> </value>
@@ -55,28 +49,13 @@
         <item>
             <key> <string>workflow_history</string> </key>
             <value>
-              <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
+              <persistent> <string encoding="base64">AAAAAAAAAAI=</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>
@@ -89,7 +68,7 @@
                 <item>
                     <key> <string>component_validation_workflow</string> </key>
                     <value>
-                      <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
+                      <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
                     </value>
                 </item>
               </dictionary>
@@ -98,7 +77,7 @@
       </dictionary>
     </pickle>
   </record>
-  <record id="4" aka="AAAAAAAAAAQ=">
+  <record id="3" aka="AAAAAAAAAAM=">
     <pickle>
       <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
     </pickle>
diff --git a/master/bt5/slapos_slap_tool/TestTemplateItem/portal_components/test.erp5.testSlapOSSlapTool.py b/master/bt5/slapos_slap_tool/TestTemplateItem/portal_components/test.erp5.testSlapOSSlapTool.py
index 86c7cfec8fbf41e95d89c7b82a111c943c304f70..1cbce80c4eb4f8b113486bc490fa76f1c01b66ac 100644
--- a/master/bt5/slapos_slap_tool/TestTemplateItem/portal_components/test.erp5.testSlapOSSlapTool.py
+++ b/master/bt5/slapos_slap_tool/TestTemplateItem/portal_components/test.erp5.testSlapOSSlapTool.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 # Copyright (c) 2002-2012 Nexedi SA and Contributors. All Rights Reserved.
-from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin
+from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin, TemporaryAlarmScript
 
 from DateTime import DateTime
 from App.Common import rfc1123_date
@@ -45,17 +45,16 @@ class TestSlapOSSlapToolMixin(SlapOSTestCaseMixin):
     SlapOSTestCaseMixin.afterSetUp(self)
     self.portal_slap = self.portal.portal_slap
 
+    self.project = self.addProject()
+
     # Prepare compute_node
-    self.compute_node = self.portal.compute_node_module.template_compute_node\
-        .Base_createCloneDocument(batch_mode=1)
+    self.compute_node = self.portal.compute_node_module\
+        .newContent(portal_type="Compute Node")
     self.compute_node.edit(
       title="Compute Node %s" % self.new_id,
-      reference="TESTCOMP-%s" % self.new_id
+      reference="TESTCOMP-%s" % self.new_id,
+      follow_up_value=self.project
     )
-    if getattr(self, "person", None) is not None:
-      self.compute_node.edit(
-        source_administration_value=getattr(self, "person", None),
-        )
     self.compute_node.validate()
     self._addCertificateLogin(self.compute_node)
 
@@ -72,7 +71,7 @@ class TestSlapOSSlapToolMixin(SlapOSTestCaseMixin):
 
 class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin):
   def test_activate_getFullComputerInformation_first_access(self):
-    self._makeComplexComputeNode(with_slave=True)
+    self._makeComplexComputeNode(self.project, with_slave=True)
     self.portal.REQUEST['disable_isTestRun'] = True
 
     self.login(self.compute_node_user_id)
@@ -242,7 +241,7 @@ class TestSlapOSSlapToolgetFullComputerInformation(TestSlapOSSlapToolMixin):
 
 class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
   def test_getFullComputerInformation(self):
-    self._makeComplexComputeNode(with_slave=True)
+    self._makeComplexComputeNode(self.project, with_slave=True)
 
     partition_1_root_instance_title = self.compute_node.partition1.getAggregateRelatedValue(
       portal_type='Software Instance').getSpecialiseValue().getTitle()
@@ -733,7 +732,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
       'recmethod': 'reportComputeNodeBang'}])
 
   def test_computerBang(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.compute_node_bang_simulator = tempfile.mkstemp()[1]
     try:
       self.login(self.compute_node_user_id)
@@ -785,7 +784,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
         os.unlink(self.compute_node_load_configuration_simulator)
   
   def test_not_accessed_getSoftwareInstallationStatus(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.compute_node_bang_simulator = tempfile.mkstemp()[1]
     self.login(self.compute_node_user_id)
     created_at = rfc1123_date(DateTime())
@@ -844,7 +843,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
         "http://example.org/foo", self.compute_node_id)
 
   def test_destroyedSoftwareRelease_noDestroyRequested(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.login(self.compute_node_user_id)
     self.assertRaises(NotFound,
         self.portal_slap.destroyedSoftwareRelease,
@@ -852,7 +851,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
         self.compute_node_id)
 
   def test_destroyedSoftwareRelease_destroyRequested(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.login(self.compute_node_user_id)
     destroy_requested = self.destroy_requested_software_installation
     self.assertEqual(destroy_requested.getValidationState(), "validated")
@@ -861,7 +860,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
     self.assertEqual(destroy_requested.getValidationState(), "invalidated")
 
   def test_availableSoftwareRelease(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.compute_node_bang_simulator = tempfile.mkstemp()[1]
     self.login(self.compute_node_user_id)
     software_installation = self.start_requested_software_installation
@@ -911,7 +910,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
   def test_buildingSoftwareRelease(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.compute_node_bang_simulator = tempfile.mkstemp()[1]
     self.login(self.compute_node_user_id)
     software_installation = self.start_requested_software_installation
@@ -961,7 +960,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
   def test_softwareReleaseError(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.compute_node_bang_simulator = tempfile.mkstemp()[1]
     self.login(self.compute_node_user_id)
     software_installation = self.start_requested_software_installation
@@ -1115,7 +1114,7 @@ class TestSlapOSSlapToolComputeNodeAccess(TestSlapOSSlapToolMixin):
 
 class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
   def test_getComputerPartitionCertificate(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     self.login(self.start_requested_software_instance.getUserId())
@@ -1150,7 +1149,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
   def test_getFullComputerInformation(self):
-    self._makeComplexComputeNode(with_slave=True)
+    self._makeComplexComputeNode(self.project, with_slave=True)
     self.login(self.start_requested_software_instance.getUserId())
     response = self.portal_slap.getFullComputerInformation(self.compute_node_id)
     self.assertEqual(200, response.status)
@@ -1292,7 +1291,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
   def test_getComputerPartitionStatus(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     created_at = rfc1123_date(DateTime())
@@ -1342,7 +1341,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
   def test_getComputerPartitionStatus_visited(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     created_at = rfc1123_date(DateTime())
@@ -1395,7 +1394,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
   def test_registerComputerPartition_withSlave(self):
-    self._makeComplexComputeNode(with_slave=True)
+    self._makeComplexComputeNode(self.project, with_slave=True)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     self.login(self.start_requested_software_instance.getUserId())
@@ -1526,7 +1525,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
   def test_registerComputerPartition(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     self.login(self.start_requested_software_instance.getUserId())
@@ -1646,7 +1645,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
       'recmethod': 'updateConnection'}])
 
   def test_setConnectionXml_withSlave(self):
-    self._makeComplexComputeNode(with_slave=True)
+    self._makeComplexComputeNode(self.project, with_slave=True)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     slave_reference = self.start_requested_slave_instance.getReference()
@@ -1680,7 +1679,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
         os.unlink(self.instance_update_connection_simulator)
 
   def test_setConnectionXml(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     connection_xml = """<marshal>
@@ -1713,7 +1712,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
         os.unlink(self.instance_update_connection_simulator)
 
   def test_softwareInstanceError(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     self.login(self.start_requested_software_instance.getUserId())
@@ -1761,7 +1760,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
   def test_softwareInstanceError_twice(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     self.login(self.start_requested_software_instance.getUserId())
@@ -1867,7 +1866,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
       'recmethod': 'bang'}])
 
   def test_softwareInstanceBang(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.instance_bang_simulator = tempfile.mkstemp()[1]
     try:
       partition_id = self.start_requested_software_instance.getAggregateValue(
@@ -1930,7 +1929,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
       'recmethod': 'rename'}])
 
   def test_softwareInstanceRename(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.instance_rename_simulator = tempfile.mkstemp()[1]
     try:
       partition_id = self.start_requested_software_instance.getAggregateValue(
@@ -1950,7 +1949,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
         os.unlink(self.instance_rename_simulator)
       
   def test_destroyedComputePartition(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     partition_id = self.destroy_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     ssl_key = self.destroy_requested_software_instance.getSslKey()
@@ -1978,7 +1977,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
       'recmethod': 'requestInstance'}])
 
   def test_request_withSlave(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.instance_request_simulator = tempfile.mkstemp()[1]
     try:
       partition_id = self.start_requested_software_instance.getAggregateValue(
@@ -1996,6 +1995,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
           filter_xml='<marshal><dictionary id="i2"/></marshal>',
           state='<marshal><string>started</string></marshal>',
           shared_xml='<marshal><bool>1</bool></marshal>',
+          project_reference=self.project.getReference()
           )
       self.assertEqual(408, response.status)
       self.assertEqual('private',
@@ -2007,13 +2007,15 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
           'state': 'started',
           'sla_xml': "<?xml version='1.0' encoding='utf-8'?>\n<instance/>\n",
           'software_type': 'req_type',
-          'shared': True})
+          'shared': True,
+          'project_reference': self.project.getReference()
+      })
     finally:
       if os.path.exists(self.instance_request_simulator):
         os.unlink(self.instance_request_simulator)
 
   def test_request(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.instance_request_simulator = tempfile.mkstemp()[1]
     try:
       partition_id = self.start_requested_software_instance.getAggregateValue(
@@ -2031,6 +2033,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
           filter_xml='<marshal><dictionary id="i2"/></marshal>',
           state='<marshal><string>started</string></marshal>',
           shared_xml='<marshal><bool>0</bool></marshal>',
+          project_reference=self.project.getReference()
           )
       self.assertEqual(408, response.status)
       self.assertEqual('private',
@@ -2042,13 +2045,15 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
           'state': 'started',
           'sla_xml': "<?xml version='1.0' encoding='utf-8'?>\n<instance/>\n",
           'software_type': 'req_type',
-          'shared': False})
+          'shared': False,
+          'project_reference': self.project.getReference()
+      })
     finally:
       if os.path.exists(self.instance_request_simulator):
         os.unlink(self.instance_request_simulator)
 
   def test_request_stopped(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.instance_request_simulator = tempfile.mkstemp()[1]
     try:
       partition_id = self.stop_requested_software_instance.getAggregateValue(
@@ -2066,6 +2071,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
           filter_xml='<marshal><dictionary id="i2"/></marshal>',
           state='<marshal><string>started</string></marshal>',
           shared_xml='<marshal><bool>0</bool></marshal>',
+          project_reference=self.project.getReference()
           )
       self.assertEqual(408, response.status)
       self.assertEqual('private',
@@ -2077,13 +2083,15 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
           'state': 'stopped',
           'sla_xml': "<?xml version='1.0' encoding='utf-8'?>\n<instance/>\n",
           'software_type': 'req_type',
-          'shared': False})
+          'shared': False,
+          'project_reference': self.project.getReference()
+      })
     finally:
       if os.path.exists(self.instance_request_simulator):
         os.unlink(self.instance_request_simulator)
 
   def test_updateInstanceSuccessorList(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
 
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
@@ -2139,7 +2147,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
             self.start_requested_software_instance.getSuccessorTitleList())
 
   def test_updateInstanceSuccessorList_one_child(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
 
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
@@ -2174,7 +2182,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
               self.start_requested_software_instance.getSuccessorTitleList())
 
   def test_updateInstanceSuccessorList_no_child(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
 
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
@@ -2211,7 +2219,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
               self.start_requested_software_instance.getSuccessorTitleList())
 
   def test_stoppedComputePartition(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     self.login(self.start_requested_software_instance.getUserId())
@@ -2258,7 +2266,7 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
   def test_startedComputePartition(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     self.login(self.start_requested_software_instance.getUserId())
@@ -2306,33 +2314,23 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
 
   def test_getSoftwareReleaseListFromSoftwareProduct(self):
     new_id = self.generateNewId()
-    software_product = self._makeSoftwareProduct(new_id)
+    software_product = self._makeSoftwareProduct(self.project, new_id=new_id,
+                                                 url='http://example.org/1.cfg')
     # 2 published software releases
-    software_release1 = self._makeSoftwareRelease(new_id)
-    software_release2 = self._makeSoftwareRelease(self.generateNewId())
-    software_release1.publish()
-    software_release2.publish()
-    # 1 released software release, should not appear
-    software_release3 = self._makeSoftwareRelease(new_id)
-    self.assertTrue(software_release3.getValidationState() == 'released')
+    software_release1 = software_product.contentValues(portal_type='Software Product Release Variation')[0]
+    software_release2 = self._makeSoftwareRelease(software_product, url='http://example.org/2.cfg')
+
     software_release1.edit(
-        aggregate_value=software_product.getRelativeUrl(),
-        url_string='http://example.org/1.cfg',
         effective_date=DateTime()
     )
     software_release2.edit(
-        aggregate_value=software_product.getRelativeUrl(),
-        url_string='http://example.org/2.cfg',
         effective_date=DateTime()
     )
-    software_release3.edit(
-        aggregate_value=software_product.getRelativeUrl(),
-        url_string='http://example.org/3.cfg'
-    )
     self.tic()
 
     response = self.portal_slap.getSoftwareReleaseListFromSoftwareProduct(
-        software_product.getReference())
+      self.project.getReference(),
+      software_product_reference=software_product.getReference())
     got_xml = etree.tostring(etree.fromstring(response),
         pretty_print=True, encoding="UTF-8", xml_declaration=True)
     expected_xml = """\
@@ -2343,40 +2341,33 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
     <string>%s</string>
   </list>
 </marshal>
-""" % (software_release2.getUrlString(), software_release1.getUrlString())
+""" % (software_release1.getUrlString(), software_release2.getUrlString())
     self.assertEqual(expected_xml, got_xml,
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
   
   def test_getSoftwareReleaseListFromSoftwareProduct_effectiveDate(self):
     new_id = self.generateNewId()
-    software_product = self._makeSoftwareProduct(new_id)
+    software_product = self._makeSoftwareProduct(self.project, new_id=new_id,
+                                                 url='http://example.org/1.cfg')
     # 3 published software releases
-    software_release1 = self._makeSoftwareRelease(new_id)
-    software_release2 = self._makeSoftwareRelease(self.generateNewId())
-    software_release3 = self._makeSoftwareRelease(self.generateNewId())
-    software_release1.publish()
-    software_release2.publish()
-    software_release3.publish()
+    software_release1 = software_product.contentValues(portal_type="Software Product Release Variation")[0]
+    software_release2 = self._makeSoftwareRelease(software_product, url='http://example.org/2.cfg')
+    software_release3 = self._makeSoftwareRelease(software_product, url='http://example.org/3.cfg')
     software_release1.edit(
-        aggregate_value=software_product.getRelativeUrl(),
-        url_string='http://example.org/1.cfg',
         effective_date=(DateTime() - 1)
     )
     # Should not be considered yet!
     software_release2.edit(
-        aggregate_value=software_product.getRelativeUrl(),
-        url_string='http://example.org/2.cfg',
         effective_date=(DateTime() + 1)
     )
     software_release3.edit(
-        aggregate_value=software_product.getRelativeUrl(),
-        url_string='http://example.org/3.cfg',
         effective_date=DateTime()
     )
     self.tic()
 
     response = self.portal_slap.getSoftwareReleaseListFromSoftwareProduct(
-        software_product.getReference())
+      self.project.getReference(),
+      software_product_reference=software_product.getReference())
     # check returned XML
     got_xml = etree.tostring(etree.fromstring(response),
         pretty_print=True, encoding="UTF-8", xml_declaration=True)
@@ -2396,10 +2387,11 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
 
   def test_getSoftwareReleaseListFromSoftwareProduct_emptySoftwareProduct(self):
     new_id = self.generateNewId()
-    software_product = self._makeSoftwareProduct(new_id)
+    software_product = self._makeSoftwareProduct(self.project, new_id=new_id)
 
     response = self.portal_slap.getSoftwareReleaseListFromSoftwareProduct(
-        software_product.getReference())
+      self.project.getReference(),
+      software_product_reference=software_product.getReference())
     got_xml = etree.tostring(etree.fromstring(response),
         pretty_print=True, encoding="UTF-8", xml_declaration=True)
     expected_xml = """\
@@ -2413,7 +2405,8 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
 
   def test_getSoftwareReleaseListFromSoftwareProduct_NoSoftwareProduct(self):
     response = self.portal_slap.getSoftwareReleaseListFromSoftwareProduct(
-        'Can I has a nonexistent software product?')
+      self.project.getReference(),
+      software_product_reference='Can I has a nonexistent software product?')
     got_xml = etree.tostring(etree.fromstring(response),
         pretty_print=True, encoding="UTF-8", xml_declaration=True)
     expected_xml = """\
@@ -2427,31 +2420,17 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
 
   def test_getSoftwareReleaseListFromSoftwareProduct_fromUrl(self):
     new_id = self.generateNewId()
-    software_product = self._makeSoftwareProduct(new_id)
+    software_product = self._makeSoftwareProduct(self.project, new_id=new_id,
+                                                 url='http://example.org/1.cfg')
     # 2 published software releases
-    software_release1 = self._makeSoftwareRelease(new_id)
-    software_release2 = self._makeSoftwareRelease(self.generateNewId())
-    software_release1.publish()
-    software_release2.publish()
-    # 1 released software release, should not appear
-    software_release3 = self._makeSoftwareRelease(new_id)
-    self.assertTrue(software_release3.getValidationState() == 'released')
-    software_release1.edit(
-        aggregate_value=software_product.getRelativeUrl(),
-        url_string='http://example.org/1.cfg'
-    )
-    software_release2.edit(
-        aggregate_value=software_product.getRelativeUrl(),
-        url_string='http://example.org/2.cfg'
-    )
-    software_release3.edit(
-        aggregate_value=software_product.getRelativeUrl(),
-        url_string='http://example.org/3.cfg'
-    )
+    software_release1 = software_product.contentValues(portal_type='Software Product Release Variation')[0]
+    software_release2 = self._makeSoftwareRelease(software_product, url='http://example.org/2.cfg')
+
     self.tic()
 
     response = self.portal_slap.getSoftwareReleaseListFromSoftwareProduct(
-        software_release_url=software_release2.getUrlString())
+      self.project.getReference(),
+      software_release_url=software_release2.getUrlString())
     # check returned XML
     got_xml = etree.tostring(etree.fromstring(response),
         pretty_print=True, encoding="UTF-8", xml_declaration=True)
@@ -2463,19 +2442,27 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
     <string>%s</string>
   </list>
 </marshal>
-""" % (software_release2.getUrlString(), software_release1.getUrlString())
+""" % (software_release1.getUrlString(), software_release2.getUrlString())
     self.assertEqual(expected_xml, got_xml,
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
 
 class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
   def afterSetUp(self):
-    password = "%s-1Aa$" % self.generateNewId() 
+    TestSlapOSSlapToolMixin.afterSetUp(self)
+
+    password = "%s-1Aa$" % self.generateNewId()
     reference = 'test_%s' % self.generateNewId()
-    person = self.portal.person_module.newContent(portal_type='Person',
+    person = self.portal.person_module.newContent(
+      portal_type='Person',
       title=reference,
-      reference=reference)
-    person.newContent(portal_type='Assignment', role='member').open()
+      reference=reference
+    )
+    person.newContent(
+      portal_type='Assignment',
+      function='customer',
+      destination_project_value=self.project
+    ).open()
     person.newContent(portal_type='ERP5 Login',
       reference=reference, password=password).validate()
 
@@ -2483,7 +2470,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
     self.person = person
     self.person_reference = person.getReference()
     self.person_user_id = person.getUserId()
-    TestSlapOSSlapToolMixin.afterSetUp(self)
+    self.tic()
 
   def test_not_accessed_getComputerStatus(self):
     self.login(self.person_user_id)
@@ -2611,7 +2598,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
         os.unlink(self.compute_node_bang_simulator)
 
   def test_getComputerPartitionStatus(self):
-    self._makeComplexComputeNode()
+    self._makeComplexComputeNode(self.project)
     self.login(self.person_user_id)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
@@ -2662,7 +2649,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
   def test_getComputerPartitionStatus_visited(self):
-    self._makeComplexComputeNode(person=self.person)
+    self._makeComplexComputeNode(self.project, person=self.person)
     self.login(self.person_user_id)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
@@ -2717,7 +2704,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
   def test_registerComputerPartition_withSlave(self):
-    self._makeComplexComputeNode(person=self.person, with_slave=True)
+    self._makeComplexComputeNode(self.project, person=self.person, with_slave=True)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     self.login(self.person_user_id)
@@ -2848,7 +2835,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
         '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
 
   def test_registerComputerPartition(self):
-    self._makeComplexComputeNode(person=self.person)
+    self._makeComplexComputeNode(self.project, person=self.person)
     partition_id = self.start_requested_software_instance.getAggregateValue(
         portal_type='Compute Partition').getReference()
     self.login(self.person_user_id)
@@ -2968,7 +2955,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
       'recmethod': 'bang'}])
 
   def test_softwareInstanceBang(self):
-    self._makeComplexComputeNode(person=self.person)
+    self._makeComplexComputeNode(self.project, person=self.person)
     self.instance_bang_simulator = tempfile.mkstemp()[1]
     try:
       partition_id = self.start_requested_software_instance.getAggregateValue(
@@ -3033,7 +3020,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
       'recmethod': 'rename'}])
 
   def test_softwareInstanceRename(self):
-    self._makeComplexComputeNode(person=self.person)
+    self._makeComplexComputeNode(self.project, person=self.person)
     self.instance_rename_simulator = tempfile.mkstemp()[1]
     try:
       partition_id = self.start_requested_software_instance.getAggregateValue(
@@ -3073,6 +3060,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
           filter_xml='<marshal><dictionary id="i2"/></marshal>',
           state='<marshal><string>started</string></marshal>',
           shared_xml='<marshal><bool>1</bool></marshal>',
+          project_reference=self.project.getReference()
           )
       self.assertEqual(408, response.status)
       self.assertEqual('private',
@@ -3084,7 +3072,9 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
           'state': 'started',
           'sla_xml': "<?xml version='1.0' encoding='utf-8'?>\n<instance/>\n",
           'software_type': 'req_type',
-          'shared': True})
+          'shared': True,
+          'project_reference': self.project.getReference()
+      })
     finally:
       if os.path.exists(self.instance_request_simulator):
         os.unlink(self.instance_request_simulator)
@@ -3103,6 +3093,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
           filter_xml='<marshal><dictionary id="i2"/></marshal>',
           state='<marshal><string>started</string></marshal>',
           shared_xml='<marshal><bool>0</bool></marshal>',
+          project_reference=self.project.getReference()
           )
       self.assertEqual(408, response.status)
       self.assertEqual('private',
@@ -3114,7 +3105,9 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
           'state': 'started',
           'sla_xml': "<?xml version='1.0' encoding='utf-8'?>\n<instance/>\n",
           'software_type': 'req_type',
-          'shared': False})
+          'shared': False,
+          'project_reference': self.project.getReference()
+      })
     finally:
       if os.path.exists(self.instance_request_simulator):
         os.unlink(self.instance_request_simulator)
@@ -3125,19 +3118,21 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
       default_email_coordinate_text="%s@example.org" % self.person.getReference(),
       career_role='member',
     )
-    self._makeComplexComputeNode(person=self.person)
+    self._makeComplexComputeNode(self.project, person=self.person)
     self.start_requested_software_instance.updateLocalRolesOnSecurityGroups()
     self.tic()
     self.login(self.person_user_id)
-    response = self.portal_slap.requestComputerPartition(
-      software_release=self.start_requested_software_instance.getUrlString(),
-      software_type=self.start_requested_software_instance.getSourceReference(),
-      partition_reference=self.start_requested_software_instance.getTitle(),
-      partition_parameter_xml='<marshal><dictionary id="i2"/></marshal>',
-      filter_xml='<marshal><dictionary id="i2"/></marshal>',
-      state='<marshal><string>started</string></marshal>',
-      shared_xml='<marshal><bool>0</bool></marshal>',
-      )
+    with TemporaryAlarmScript(self.portal, 'Item_getSubscriptionStatus', "'subscribed'"):
+      response = self.portal_slap.requestComputerPartition(
+        software_release=self.start_requested_software_instance.getUrlString(),
+        software_type=self.start_requested_software_instance.getSourceReference(),
+        partition_reference=self.start_requested_software_instance.getTitle(),
+        partition_parameter_xml='<marshal><dictionary id="i2"/></marshal>',
+        filter_xml='<marshal><dictionary id="i2"/></marshal>',
+        state='<marshal><string>started</string></marshal>',
+        shared_xml='<marshal><bool>0</bool></marshal>',
+        project_reference=self.project.getReference()
+        )
     self.assertEqual(type(response), str)
     # check returned XML
     got_xml = etree.tostring(etree.fromstring(response),
@@ -3251,7 +3246,7 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
       compute_node_id = 'Foo Compute Node'
       compute_node_reference = 'live_comp_%s' % self.generateNewId()
       self.portal.REQUEST.set('compute_node_reference', compute_node_reference)
-      response = self.portal_slap.requestComputer(compute_node_id)
+      response = self.portal_slap.requestComputer(compute_node_id, self.project.getReference())
       got_xml = etree.tostring(etree.fromstring(response),
         pretty_print=True, encoding="UTF-8", xml_declaration=True)
       expected_xml = """\
@@ -3271,7 +3266,8 @@ class TestSlapOSSlapToolPersonAccess(TestSlapOSSlapToolMixin):
 
       self.assertEqual(expected_xml, got_xml,
           '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
-      self.assertRequestComputeNodeSimulator((), {'compute_node_title': compute_node_id})
+      self.assertRequestComputeNodeSimulator((), {'compute_node_title': compute_node_id,
+                                                  'project_reference': self.project.getReference()})
     finally:
       if os.path.exists(self.compute_node_request_compute_node_simulator):
         os.unlink(self.compute_node_request_compute_node_simulator)
diff --git a/master/bt5/slapos_slap_tool/TestTemplateItem/portal_components/test.erp5.testSlapOSSlapToolComputeNodeUpdateFromDict.py b/master/bt5/slapos_slap_tool/TestTemplateItem/portal_components/test.erp5.testSlapOSSlapToolComputeNodeUpdateFromDict.py
index 9b099aa7745292a56265177f294e5d0ae7e57e27..331640821f084de5b238cb56a0f7610a53d902db 100644
--- a/master/bt5/slapos_slap_tool/TestTemplateItem/portal_components/test.erp5.testSlapOSSlapToolComputeNodeUpdateFromDict.py
+++ b/master/bt5/slapos_slap_tool/TestTemplateItem/portal_components/test.erp5.testSlapOSSlapToolComputeNodeUpdateFromDict.py
@@ -5,8 +5,8 @@ class TestSlapOSCoreComputeNodeUpdateFromDict(SlapOSTestCaseMixinWithAbort):
 
   def afterSetUp(self):
     SlapOSTestCaseMixinWithAbort.afterSetUp(self)
-    self.compute_node = self.portal.compute_node_module.template_compute_node\
-        .Base_createCloneDocument(batch_mode=1)
+    self.compute_node = self.portal.compute_node_module\
+        .newContent(portal_type="Compute Node")
     self.compute_node.edit(
       reference='TESTC-%s' % self.generateNewId(),
     )
diff --git a/master/bt5/slapos_slap_tool/ToolComponentTemplateItem/portal_components/tool.erp5.SlapTool.py b/master/bt5/slapos_slap_tool/ToolComponentTemplateItem/portal_components/tool.erp5.SlapTool.py
index d637207f8d50ebf6f095d29e97bf1a1bd5aea25e..9d5b2d254fc45967e4a9f1592790252187f50fd2 100644
--- a/master/bt5/slapos_slap_tool/ToolComponentTemplateItem/portal_components/tool.erp5.SlapTool.py
+++ b/master/bt5/slapos_slap_tool/ToolComponentTemplateItem/portal_components/tool.erp5.SlapTool.py
@@ -371,7 +371,7 @@ class SlapTool(BaseTool):
 
   security.declareProtected(Permissions.AccessContentsInformation,
     'getSoftwareReleaseListFromSoftwareProduct')
-  def getSoftwareReleaseListFromSoftwareProduct(self,
+  def getSoftwareReleaseListFromSoftwareProduct(self, project_reference,
       software_product_reference=None, software_release_url=None):
     """
     Get the list of all published Software Releases related to one of either:
@@ -382,12 +382,23 @@ class SlapTool(BaseTool):
     If referenced Software Product does not exist, return empty list.
     If referenced Software Release does not exist, raise.
     """
+    project_list = self.getPortalObject().portal_catalog.portal_catalog(
+      portal_type='Project',
+      reference=project_reference,
+      validation_state='validated',
+      limit=2
+    )
+    if len(project_list) != 1:
+      raise NotImplementedError("%i projects '%s'" % (len(project_list), project_reference))
+    project = project_list[0]
+
     if software_product_reference is None:
       assert(software_release_url is not None)
       software_product_reference = self.getPortalObject().portal_catalog.unrestrictedSearchResults(
-        portal_type='Software Release',
+        portal_type='Software Product Release Variation',
+        parent__follow_up__uid=project.getUid(),
         url_string=software_release_url
-      )[0].getObject().getAggregateValue().getReference()
+      )[0].getObject().getParentValue().getReference()
     else:
       # Don't accept both parameters
       assert(software_release_url is None)
@@ -395,13 +406,14 @@ class SlapTool(BaseTool):
     software_product_list = self.getPortalObject().portal_catalog.unrestrictedSearchResults(
       portal_type='Software Product',
       reference=software_product_reference,
+      follow_up__uid=project.getUid(),
       validation_state='published')
     if len(software_product_list) is 0:
       return dumps([])
     if len(software_product_list) > 1:
       raise NotImplementedError('Several Software Product with the same title.')
     software_release_list = \
-        software_product_list[0].getObject().getAggregateRelatedValueList()
+        software_product_list[0].getObject().contentValues(portal_type='Software Product Release Variation')
     
     def sortkey(software_release):
       publication_date = software_release.getEffectiveDate()
@@ -418,9 +430,7 @@ class SlapTool(BaseTool):
     )
     return dumps(
       [software_release.getUrlString()
-        for software_release in software_release_list
-          if software_release.getValidationState() in \
-                  ['published', 'published_alive']])
+        for software_release in software_release_list])
 
   security.declareProtected(Permissions.AccessContentsInformation,
     'getHateoasUrl')
@@ -506,20 +516,20 @@ class SlapTool(BaseTool):
     return self._supplySupply(url, computer_id, state)
 
   @convertToREST
-  def _requestComputeNode(self, compute_node_title):
+  def _requestComputeNode(self, compute_node_title, project_reference):
     portal = self.getPortalObject()
     person = portal.portal_membership.getAuthenticatedMember().getUserValue()
-    person.requestComputeNode(compute_node_title=compute_node_title)
+    person.requestComputeNode(compute_node_title=compute_node_title, project_reference=project_reference)
     compute_node = ComputeNode(self.REQUEST.get('compute_node_reference').decode("UTF-8"))
     return dumps(compute_node)
 
   security.declareProtected(Permissions.AccessContentsInformation,
     'requestComputer')
-  def requestComputer(self, computer_title):
+  def requestComputer(self, computer_title, project_reference):
     """
     Request Compute Node
     """
-    return self._requestComputeNode(computer_title)
+    return self._requestComputeNode(computer_title, project_reference)
 
   security.declareProtected(Permissions.AccessContentsInformation,
     'buildingSoftwareRelease')
@@ -613,7 +623,7 @@ class SlapTool(BaseTool):
   def requestComputerPartition(self, computer_id=None,
       computer_partition_id=None, software_release=None, software_type=None,
       partition_reference=None, partition_parameter_xml=None,
-      filter_xml=None, state=None, shared_xml=_MARKER):
+      filter_xml=None, state=None, shared_xml=_MARKER, project_reference=None):
     """
     Asynchronously requests creation of compute partition for assigned
     parameters
@@ -627,7 +637,8 @@ class SlapTool(BaseTool):
     """
     return self._requestComputePartition(computer_id, computer_partition_id,
         software_release, software_type, partition_reference,
-        shared_xml, partition_parameter_xml, filter_xml, state)
+        shared_xml, partition_parameter_xml, filter_xml, state,
+        project_reference)
 
   security.declareProtected(Permissions.AccessContentsInformation,
     'useComputer')
@@ -924,7 +935,8 @@ class SlapTool(BaseTool):
   @convertToREST
   def _requestComputePartition(self, compute_node_id, compute_partition_id,
         software_release, software_type, partition_reference,
-        shared_xml, partition_parameter_xml, filter_xml, state):
+        shared_xml, partition_parameter_xml, filter_xml, state,
+        project_reference):
     """
     Asynchronously requests creation of compute partition for assigned
     parameters
@@ -962,7 +974,8 @@ class SlapTool(BaseTool):
               instance_xml=castToStr(partition_parameter_kw),
               shared=shared,
               sla_xml=castToStr(filter_kw),
-              state=state)
+              state=state,
+              project_reference=project_reference)
 
     portal = self.getPortalObject()
     if compute_node_id and compute_partition_id: