diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/Computer_checkAndCreateUpgradeDecision.xml b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/Computer_checkAndCreateUpgradeDecision.xml
index da36fa8024d9058f27ca7bda0a9b4c998890d2af..618fa23aeb9bc3a407f2d8db00c75d675df91716 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/Computer_checkAndCreateUpgradeDecision.xml
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/Computer_checkAndCreateUpgradeDecision.xml
@@ -53,12 +53,12 @@
             <value> <string>computer = context\n
 portal = context.getPortalObject()\n
 \n
-full_software_release_list = [si.getUrlString() for si in \n
-          portal.portal_catalog(\n
-            portal_type=\'Software Installation\',\n
-            default_aggregate_uid=computer.getUid(),\n
-            validation_state=\'validated\'\n
-          ) if si.getSlapState() == \'start_requested\']\n
+full_software_release_list = [si.getUrlString() for si in\n
+              portal.portal_catalog(\n
+                portal_type=\'Software Installation\',\n
+                default_aggregate_uid=computer.getUid(),\n
+                validation_state=\'validated\'\n
+              ) if si.getSlapState() == \'start_requested\']\n
 \n
 if len(full_software_release_list) == 0:\n
   return\n
@@ -68,7 +68,7 @@ software_release_list = portal.portal_catalog(\n
                           url_string=full_software_release_list,\n
                           group_by=\'default_aggregate_uid\'\n
                         )\n
-\n
+upgrade_decision_list = []\n
 for software_release in software_release_list:\n
   software_product_reference = software_release.getAggregateReference()\n
   sorted_list = portal.SoftwareProduct_getSortedSoftwareReleaseList(\n
@@ -81,15 +81,21 @@ for software_release in software_release_list:\n
     newer_release = sorted_list[0]\n
     title = \'A new software release is available for %s\' % \\\n
                         software_product_reference\n
-    # Search if exist upgrade decision for this software product (by title)\n
-    is_decision_in_progress = newer_release.\\\n
-            SoftwareRelease_isUpgradeDecisionInProgress(title=title)\n
-    if is_decision_in_progress:\n
+    # If exist upgrade decision in progress try to cancel it\n
+    decision_in_progress = newer_release.\\\n
+            SoftwareRelease_getUpgradeDecisionInProgress(computer.getUid())\n
+    if decision_in_progress and \\\n
+        not decision_in_progress.UpgradeDecision_tryToCancel(\n
+          newer_release.getUrlString()):\n
       continue\n
   \n
-    return newer_release.SoftwareRelease_createUpgradeDecision(\n
-        source_url=computer.getRelativeUrl(), title=title\n
-      )\n
+    upgrade_decision = newer_release.SoftwareRelease_createUpgradeDecision(\n
+        source_url=computer.getRelativeUrl(),\n
+        title=title)\n
+    upgrade_decision.confirm()\n
+    upgrade_decision_list.append(upgrade_decision)\n
+\n
+return upgrade_decision_list\n
 </string> </value>
         </item>
         <item>
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/Computer_hostingSubscriptionCreateUpgradeDecision.xml b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/Computer_hostingSubscriptionCreateUpgradeDecision.xml
index 0dbe13132cb812be5e9f28bd8023e4b060d30ab3..432a7c891c170efdd34890ca987b2139380b4bc4 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/Computer_hostingSubscriptionCreateUpgradeDecision.xml
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/Computer_hostingSubscriptionCreateUpgradeDecision.xml
@@ -50,30 +50,30 @@
         </item>
         <item>
             <key> <string>_body</string> </key>
-            <value> <string>computer = context\n
-portal = context.getPortalObject()\n
+            <value> <string>portal = context.getPortalObject()\n
 \n
 partition_list = portal.portal_catalog(portal_type=\'Computer Partition\',\n
                                         free_for_request=0,\n
-                                        parent_uid=computer.getUid())\n
+                                        parent_uid=context.getUid())\n
+valid_slap_state = [\'start_requested\', \'stop_requested\']\n
 \n
-# Get Hosting Subscription for all allocated partition\n
 hosting_subscription_list = []\n
+upgrade_decision_list = []\n
 for partition in partition_list:\n
   software_instance = partition.getAggregateRelatedValue(\n
                             portal_type=\'Software Instance\')\n
-  if software_instance:\n
-    hs = software_instance.getSpecialiseValue(\n
-                  portal_type=\'Hosting Subscription\')\n
-    if hs and hs.getSlapState() in \\\n
-        [\'start_requested\', \'stop_requested\'] and \\\n
-        not hs in hosting_subscription_list:\n
-      hosting_subscription_list.append(hs)\n
+  if not software_instance:\n
+    continue\n
 \n
-if len(hosting_subscription_list) == 0:\n
-  return\n
+  hosting_subscription = software_instance.getSpecialiseValue(\n
+                portal_type=\'Hosting Subscription\')\n
+  if hosting_subscription and hosting_subscription.getSlapState() \\\n
+      in valid_slap_state and not \\\n
+      hosting_subscription in hosting_subscription_list:\n
+    hosting_subscription_list.append(hosting_subscription)\n
+  else:\n
+    continue\n
 \n
-for hosting_subscription in hosting_subscription_list:\n
   is_upgradable = hosting_subscription.HostingSubscription_isUpgradable()\n
   if not is_upgradable:\n
     continue\n
@@ -82,7 +82,8 @@ for hosting_subscription in hosting_subscription_list:\n
                     HostingSubscription_getNewerSofwareRelease()\n
   if not newer_release_string:\n
     continue\n
-  \n
+  # XXX - Should try to change method HostingSubscription_getNewerSofwareRelease\n
+  # to return software_release object directly\n
   software_release = portal.portal_catalog.getResultValue(\n
                               portal_type=\'Software Release\',\n
                               url_string=newer_release_string)\n
@@ -91,15 +92,20 @@ for hosting_subscription in hosting_subscription_list:\n
   \n
   title = \'A new software release is available for %s\' % \\\n
                         hosting_subscription.getReference()\n
-  # Search if exist upgrade decision for this Hosting Subscription (by title)\n
-  is_decision_in_progress = software_release.\\\n
-          SoftwareRelease_isUpgradeDecisionInProgress(title=title)\n
-  if is_decision_in_progress:\n
+  decision_in_progress = software_release.\\\n
+      SoftwareRelease_getUpgradeDecisionInProgress(hosting_subscription.getUid())\n
+  \n
+  if decision_in_progress and \\\n
+      not decision_in_progress.UpgradeDecision_tryToCancel(newer_release_string):\n
     continue\n
+  \n
+  upgrade_decision = software_release.SoftwareRelease_createUpgradeDecision(\n
+    source_url=hosting_subscription.getRelativeUrl(),\n
+    title=title)\n
+  upgrade_decision.confirm()\n
+  upgrade_decision_list.append(upgrade_decision)\n
 \n
-  return software_release.SoftwareRelease_createUpgradeDecision(\n
-      source_url=hosting_subscription.getRelativeUrl(), title=title\n
-    )\n
+return upgrade_decision_list\n
 </string> </value>
         </item>
         <item>
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/SoftwareRelease_createUpgradeDecision.xml b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/SoftwareRelease_createUpgradeDecision.xml
index 23ddc9c5c39e02112033aaa67dab89bae0b5ecdf..e993042262be4dce62f3fb90b5b135c3eb7df1d7 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/SoftwareRelease_createUpgradeDecision.xml
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/SoftwareRelease_createUpgradeDecision.xml
@@ -55,8 +55,8 @@
 from DateTime import DateTime\n
 \n
 portal = context.getPortalObject()\n
-\n
 software_release = context\n
+\n
 source_product = portal.restrictedTraverse(source_url, None)\n
 if not source_product:\n
   return\n
@@ -73,14 +73,12 @@ if not person_url:\n
   return\n
 \n
 upgrade_decision = portal.upgrade_decision_module.\\\n
-            template_upgrade_decision.Base_createCloneDocument(batch_mode=1) \n
+            template_upgrade_decision.Base_createCloneDocument(batch_mode=1)\n
 upgrade_decision.edit(\n
         title=title,\n
         destination_section=person_url,\n
-        destination_decision=person_url,\n
-        start_date=DateTime()\n
+        destination_decision=person_url\n
 )\n
-upgrade_decision.confirm()\n
 decision_line_list = upgrade_decision.contentValues(\n
                     portal_type=\'Upgrade Decision Line\')\n
 if len(decision_line_list) > 0:\n
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/SoftwareRelease_getUpgradeDecisionInProgress.xml b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/SoftwareRelease_getUpgradeDecisionInProgress.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3cdde91c8f7353540e02b71367b34af03265424b
--- /dev/null
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/SoftwareRelease_getUpgradeDecisionInProgress.xml
@@ -0,0 +1,90 @@
+<?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>_body</string> </key>
+            <value> <string encoding="cdata"><![CDATA[
+
+portal = context.getPortalObject()\n
+product_reference = context.getAggregateReference()\n
+\n
+decision_line_in_progress_list = portal.portal_catalog(\n
+                    portal_type=\'Upgrade Decision Line\',\n
+                    aggregate_uid=aggregate_uid)\n
+\n
+for decision_line in decision_line_in_progress_list:\n
+  upgrade_decision = decision_line.getParentValue()\n
+  if upgrade_decision.getSimulationState() not in [\'planned\',\n
+      \'confirmed\', \'started\', \'stopped\']:\n
+    continue\n
+  release_list = decision_line.getAggregateValueList(portal_type="Software Release")\n
+  if len(release_list) > 1:\n
+    continue\n
+  if not release_list[0]:\n
+    continue\n
+  # If both software release belong to the same software product, there is an upgrade decision in progress \n
+  if product_reference == release_list[0].getAggregateReference():\n
+    return upgrade_decision\n
+
+
+]]></string> </value>
+        </item>
+        <item>
+            <key> <string>_params</string> </key>
+            <value> <string>aggregate_uid</string> </value>
+        </item>
+        <item>
+            <key> <string>id</string> </key>
+            <value> <string>SoftwareRelease_getUpgradeDecisionInProgress</string> </value>
+        </item>
+      </dictionary>
+    </pickle>
+  </record>
+</ZopeData>
diff --git a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/SoftwareRelease_isUpgradeDecisionInProgress.xml b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_tryToCancel.xml
similarity index 72%
rename from master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/SoftwareRelease_isUpgradeDecisionInProgress.xml
rename to master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_tryToCancel.xml
index 801510fdfe0703844d19ec1ed4c0689e026f8ec6..f5ed4aa15c15cc8b20f8145f6d331436185d963f 100644
--- a/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/SoftwareRelease_isUpgradeDecisionInProgress.xml
+++ b/master/bt5/slapos_pdm/SkinTemplateItem/portal_skins/slapos_pdm/UpgradeDecision_tryToCancel.xml
@@ -50,39 +50,30 @@
         </item>
         <item>
             <key> <string>_body</string> </key>
-            <value> <string>url_string = context.getUrlString()\n
-portal = context.getPortalObject()\n
+            <value> <string>upgrade_decision = context\n
+cancel_state_list = [\'confirmed\', \'planned\']\n
 \n
-# Check if there is an upgrade decision in progress\n
-kw[\'portal_type\'] = \'Upgrade Decision\'\n
-upgrade_decision_in_progress = portal.portal_catalog(**kw)\n
-\n
-if len(upgrade_decision_in_progress) == 0:\n
+if upgrade_decision.getSimulationState() in cancel_state_list:\n
+  current_release = upgrade_decision.UpgradeDecision_getSoftwareRelease()\n
+  if not current_release:\n
+    # This upgrade decision is not valid\n
+    return True\n
+  if current_release.getUrlString() == new_url_string:\n
+    # Cannot cancel because the software releases are the same\n
+    return False\n
+  upgrade_decision.cancel()\n
+  return True\n
+else:\n
   return False\n
-\n
-in_progress = False\n
-for decision_in_progress in upgrade_decision_in_progress:\n
-  try:\n
-    software_release = decision_in_progress.\\\n
-              UpgradeDecision_getSoftwareRelease()\n
-  except ValueError:\n
-    continue\n
-  if not software_release:\n
-    continue\n
-  if url_string == software_release.getUrlString():\n
-    in_progress = True\n
-    break\n
-\n
-return in_progress\n
 </string> </value>
         </item>
         <item>
             <key> <string>_params</string> </key>
-            <value> <string>**kw</string> </value>
+            <value> <string>new_url_string</string> </value>
         </item>
         <item>
             <key> <string>id</string> </key>
-            <value> <string>SoftwareRelease_isUpgradeDecisionInProgress</string> </value>
+            <value> <string>UpgradeDecision_tryToCancel</string> </value>
         </item>
       </dictionary>
     </pickle>
diff --git a/master/bt5/slapos_pdm/TestTemplateItem/testSlapOSPDMSkins.py b/master/bt5/slapos_pdm/TestTemplateItem/testSlapOSPDMSkins.py
index 0b6823a5f0dd6ba65e1e59c45a3bb763e0c62261..5ebd172b294ee362c5f5c5701ee9b796324a0dce 100644
--- a/master/bt5/slapos_pdm/TestTemplateItem/testSlapOSPDMSkins.py
+++ b/master/bt5/slapos_pdm/TestTemplateItem/testSlapOSPDMSkins.py
@@ -27,29 +27,10 @@
 ##############################################################################
 
 import transaction
-from functools import wraps
 from Products.SlapOS.tests.testSlapOSMixin import testSlapOSMixin
 from Products.ERP5Type.tests.utils import createZODBPythonScript
 from DateTime import DateTime
 
-def simulate(script_id, params_string, code_string):
-  def upperWrap(f):
-    @wraps(f)
-    def decorated(self, *args, **kw):
-      if script_id in self.portal.portal_skins.custom.objectIds():
-        raise ValueError('Precondition failed: %s exists in custom' % script_id)
-      createZODBPythonScript(self.portal.portal_skins.custom,
-                          script_id, params_string, code_string)
-      try:
-        result = f(self, *args, **kw)
-      finally:
-        if script_id in self.portal.portal_skins.custom.objectIds():
-          self.portal.portal_skins.custom.manage_delObjects(script_id)
-        transaction.commit()
-      return result
-    return decorated
-  return upperWrap
-
 class TestSlapOSPDMSkins(testSlapOSMixin):
   def afterSetUp(self):
     super(TestSlapOSPDMSkins, self).afterSetUp()
@@ -62,14 +43,6 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
         shared=False,
         state="started"
     )
-  
-  def beforeTearDown(self):
-    id_list = []
-    for upgrade_decision in self.portal.portal_catalog(
-               portal_type="Upgrade Decision", reference="UD-TEST%"):
-      id_list.append(upgrade_decision.getId())
-    self.portal.upgrade_decision_module.manage_delObjects(id_list)
-    self.tic()
 
   def generateNewId(self):
      return "%sTEST" % self.portal.portal_ids.generateNewId(
@@ -277,6 +250,7 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
     self.assertEquals(computer.getRelativeUrl(),
                       found_computer.getRelativeUrl())
 
+
   def testUpgradeDecision_getComputer_2_computer(self):
     computer = self._makeComputer(self.new_id)
     upgrade_decision = self._makeUpgradeDecision()
@@ -296,6 +270,17 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
     found_computer = upgrade_decision.UpgradeDecision_getComputer()
     self.assertEquals(None, found_computer)
 
+     
+  def testUpgradeDecision_getSoftwareRelease(self):
+    software_release = self._makeSoftwareRelease(self.new_id)
+    upgrade_decision = self._makeUpgradeDecision()
+
+    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
+    upgrade_decision_line.setAggregateValue(software_release)
+
+    found_software_release = upgrade_decision.UpgradeDecision_getSoftwareRelease()
+    self.assertEquals(software_release.getRelativeUrl(),
+                      found_software_release.getRelativeUrl())
 
   def testUpgradeDecision_getHostingSubscription(self):
     hosting_subscription = self._makeHostingSubscription(self.new_id)
@@ -423,43 +408,6 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
     self.assertEqual(slap_state, hosting_subscription.getSlapState())
     self.assertEqual('stopped', upgrade_decision.getSimulationState())
 
-  def testUpgradeDecision_processUpgradeeHostingSubscription(self):
-    person = self._makePerson(self.new_id)
-    hosting_subscription = self._makeHostingSubscription(self.new_id)
-    hosting_subscription.edit(
-          destination_section_value = person.getRelativeUrl())
-
-    self._makeSoftwareInstance(hosting_subscription,
-                               hosting_subscription.getUrlString())
-   
-    software_release = self._makeSoftwareRelease(self.new_id)
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList(
-       [software_release, hosting_subscription])
-    self.tic()
-   
-    slap_state = hosting_subscription.getSlapState()
-    
-    self.assertFalse(upgrade_decision.UpgradeDecision_processUpgrade())
-    self.assertNotEqual(software_release.getUrlString(),
-                     hosting_subscription.getUrlString())
-
-    upgrade_decision.confirm()
-    upgrade_decision.start()
-
-    # Check that url_string change, but slap state doesn't
-    self.assertNotEqual(software_release.getUrlString(),
-                     hosting_subscription.getUrlString())
-
-    self.assertTrue(upgrade_decision.UpgradeDecision_processUpgrade())
-    self.assertEqual(software_release.getUrlString(),
-                     hosting_subscription.getUrlString())
-
-    self.assertEqual(slap_state, hosting_subscription.getSlapState())
-    self.assertEqual('stopped', upgrade_decision.getSimulationState())
-
-
   def testUpgradeDecision_upgradeHostingSubscription_no_software_release(self):
 
     person = self._makePerson(self.new_id)
@@ -555,33 +503,6 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
     self.assertEqual('stopped', upgrade_decision.getSimulationState())
 
 
-  def testUpgradeDecision_processUpgradeComputer(self):
-    person = self._makePerson(self.new_id)
-    computer = self._makeComputer(self.new_id)
-    software_release = self._makeSoftwareRelease(self.new_id)
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList([software_release, computer])
-    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 = computer.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_computer(self):
     person = self._makePerson(self.new_id)
     computer = self._makeComputer(self.new_id)
@@ -593,7 +514,7 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
           title="TEST-SRUPDE-%s" % self.new_id)
     self.tic()
     
-    self.assertEqual(upgrade_decision.getSimulationState(), 'confirmed')
+    self.assertEqual(upgrade_decision.getSimulationState(), 'draft')
     self.assertEqual(upgrade_decision.getDestinationSection(),
                        person.getRelativeUrl())
     
@@ -622,7 +543,7 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
           title="TEST-SRUPDE-%s" % self.new_id)
     self.tic()
     
-    self.assertEqual(upgrade_decision.getSimulationState(), 'confirmed')
+    self.assertEqual(upgrade_decision.getSimulationState(), 'draft')
     self.assertEqual(upgrade_decision.getDestinationSection(),
                        person.getRelativeUrl())
     
@@ -635,37 +556,179 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
                       software_release.getRelativeUrl())
   
   
-  def testSoftwareRelease_isUpgradeDecisionInProgress(self):
+  def testSoftwareRelease_getUpgradeDecisionInProgress(self):
     computer = self._makeComputer(self.new_id)
-    software_release = self._makeSoftwareRelease(self.new_id)
+    software_product = self._makeSoftwareProduct(self.new_id)
+    software_release = self._requestSoftwareRelease(self.new_id,
+                                    software_product.getRelativeUrl())
     upgrade_decision = self._makeUpgradeDecision()
     upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
     upgrade_decision_line.setAggregateValueList([software_release, computer])
     software_release2 = self._makeSoftwareRelease(self.generateNewId())
     upgrade_decision.confirm()
+    reference = upgrade_decision.getReference()
+    
+    self.tic()
+    
+    in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
+                                computer.getUid())
+    self.assertEqual(in_progress.getReference(), reference)
+    
+    in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
+                                software_release.getUid())
+    self.assertEqual(in_progress.getReference(), reference)
+    
+    in_progress = software_release2.SoftwareRelease_getUpgradeDecisionInProgress(
+                                computer.getUid())
+    self.assertEqual(in_progress, None)
+  
+  def testSoftwareRelease_getUpgradeDecisionInProgress_cancelled(self):
+    computer = self._makeComputer(self.new_id)
+    software_product = self._makeSoftwareProduct(self.new_id)
+    software_release = self._requestSoftwareRelease(self.new_id,
+                                    software_product.getRelativeUrl())
+    upgrade_decision = self._makeUpgradeDecision()
+    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
+    upgrade_decision_line.setAggregateValueList([software_release, computer])
+    upgrade_decision.confirm()
+    upgrade_decision.cancel()
     
     self.tic()
+    in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
+                                computer.getUid())
+    self.assertEqual(in_progress, None)
     
-    in_progress = software_release.SoftwareRelease_isUpgradeDecisionInProgress(
-                                title=upgrade_decision.getTitle()
-                              )
-    self.assertEqual(in_progress, True)
+    upgrade_decision2 = self._makeUpgradeDecision()
+    upgrade_decision_line2 = self._makeUpgradeDecisionLine(upgrade_decision2)
+    upgrade_decision_line2.setAggregateValueList([software_release, computer])
+    upgrade_decision2.confirm()
+    upgrade_decision2.start()
+    self.tic()
     
-    in_progress = software_release.SoftwareRelease_isUpgradeDecisionInProgress()
-    self.assertEqual(in_progress, True)
+    in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
+                                computer.getUid())
+    self.assertEqual(in_progress.getReference(), upgrade_decision2.getReference())
+  
+  def testSoftwareRelease_getUpgradeDecisionInProgress_hosting_subs(self):
+    person = self._makePerson(self.new_id)
+    hosting_subscription = self._makeHostingSubscription(self.new_id)
+    hosting_subscription.edit(
+          destination_section_value = person.getRelativeUrl())
+    software_product = self._makeSoftwareProduct(self.new_id)
+    software_release = self._requestSoftwareRelease(self.new_id,
+                                    software_product.getRelativeUrl())
+    upgrade_decision = self._makeUpgradeDecision()
+    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
+    upgrade_decision_line.setAggregateValueList([software_release,
+                                                      hosting_subscription])
+    upgrade_decision.confirm()
+    reference = upgrade_decision.getReference()
+    self.tic()
     
-    in_progress = software_release.SoftwareRelease_isUpgradeDecisionInProgress(
-                                title=upgrade_decision.getTitle(),
-                                simulation_state='stopped'
-                              )
-    self.assertEqual(in_progress, False)
+    in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
+                                hosting_subscription.getUid())
+    self.assertEqual(in_progress.getReference(), reference)
     
-    in_progress = software_release2.SoftwareRelease_isUpgradeDecisionInProgress(
-                                title=upgrade_decision.getTitle()
-                              )
-    self.assertEqual(in_progress, False)
+    upgrade_decision.cancel()
+    self.tic()
     
+    in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
+                                hosting_subscription.getUid())
+    self.assertEqual(in_progress, None)
   
+  
+  def testSoftwareRelease_getUpgradeDecisionInProgress_software_product(self):
+    computer = self._makeComputer(self.new_id)
+    software_product = self._makeSoftwareProduct(self.new_id)
+    software_release = self._requestSoftwareRelease(self.new_id,
+                                    software_product.getRelativeUrl())
+    software_release2 = self._requestSoftwareRelease(self.generateNewId(),
+                                      software_product.getRelativeUrl())
+    software_release3 = self._makeSoftwareRelease(self.generateNewId())
+    upgrade_decision = self._makeUpgradeDecision()
+    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
+    upgrade_decision_line.setAggregateValueList([software_release, computer])
+    upgrade_decision.confirm()
+    reference = upgrade_decision.getReference()
+    
+    self.tic()
+    
+    in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
+                                computer.getUid())
+    self.assertEqual(in_progress.getReference(), reference)
+    
+    in_progress = software_release2.SoftwareRelease_getUpgradeDecisionInProgress(
+                                computer.getUid())
+    self.assertEqual(in_progress.getReference(), reference)
+    
+    in_progress = software_release3.SoftwareRelease_getUpgradeDecisionInProgress(
+                                computer.getUid())
+    self.assertEqual(in_progress, None)
+  
+  
+  def testSoftwareRelease_getUpgradeDecisionInProgress_software_product_hs(self):
+    person = self._makePerson(self.new_id)
+    hosting_subscription = self._makeHostingSubscription(self.new_id)
+    hosting_subscription.edit(
+          destination_section_value = person.getRelativeUrl())
+    software_product = self._makeSoftwareProduct(self.new_id)
+    software_release = self._requestSoftwareRelease(self.new_id,
+                                    software_product.getRelativeUrl())
+    software_release2 = self._requestSoftwareRelease(self.generateNewId(),
+                                      software_product.getRelativeUrl())
+    software_release3 = self._makeSoftwareRelease(self.generateNewId())
+    upgrade_decision = self._makeUpgradeDecision()
+    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
+    upgrade_decision_line.setAggregateValueList([software_release,
+                                                      hosting_subscription])
+    upgrade_decision.confirm()
+    reference = upgrade_decision.getReference()
+    reference = upgrade_decision.getReference()
+    
+    self.tic()
+    
+    in_progress = software_release.SoftwareRelease_getUpgradeDecisionInProgress(
+                                hosting_subscription.getUid())
+    self.assertEqual(in_progress.getReference(), reference)
+    
+    in_progress = software_release2.SoftwareRelease_getUpgradeDecisionInProgress(
+                                hosting_subscription.getUid())
+    self.assertEqual(in_progress.getReference(), reference)
+    
+    in_progress = software_release3.SoftwareRelease_getUpgradeDecisionInProgress(
+                                hosting_subscription.getUid())
+    self.assertEqual(in_progress, None)
+  
+  
+  def testUpgradeDecision_tryToCancel(self):
+    computer = self._makeComputer(self.new_id)
+    software_release = self._makeSoftwareRelease(self.new_id)
+    software_release2 = self._makeSoftwareRelease(self.generateNewId())
+    upgrade_decision = self._makeUpgradeDecision()
+    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
+    upgrade_decision_line.setAggregateValueList([software_release, computer])
+    upgrade_decision.confirm()
+    
+    upgrade_decision2 = self._makeUpgradeDecision()
+    upgrade_decision_line2 = self._makeUpgradeDecisionLine(upgrade_decision2)
+    upgrade_decision_line2.setAggregateValueList([software_release, computer])
+    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 testComputer_checkAndCreateUpgradeDecision(self):
     person = self._makePerson(self.new_id)
     computer = self._makeComputer(self.new_id)
@@ -676,9 +739,8 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
     self._makeSoftwareInstallation(self.new_id,
                               computer, software_release.getUrlString())
     self.tic()
-    
     upgrade_decision = computer.Computer_checkAndCreateUpgradeDecision()
-    self.assertEqual(upgrade_decision, None)
+    self.assertEqual(len(upgrade_decision), 0)
     
     software_release2 = self._requestSoftwareRelease(self.generateNewId(),
                                       software_product.getRelativeUrl())
@@ -689,21 +751,48 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
     self.tic()
     
     upgrade_decision = computer.Computer_checkAndCreateUpgradeDecision()
+    self.assertEqual(len(upgrade_decision), 1)
+    self.assertEqual(upgrade_decision[0].getSimulationState(), 'confirmed')
     
-    self.assertEqual(upgrade_decision.getSimulationState(), 'confirmed')
-    
-    computer_aggregate = upgrade_decision.UpgradeDecision_getComputer()
+    computer_aggregate = upgrade_decision[0].UpgradeDecision_getComputer()
     self.assertEqual(computer_aggregate.getReference(),
                       computer.getReference())
-    url_string = upgrade_decision.UpgradeDecision_getSoftwareRelease()
-    self.assertEqual(url_string.getUrlString(),
+    release = upgrade_decision[0].UpgradeDecision_getSoftwareRelease()
+    self.assertEqual(release.getUrlString(),
                                 software_release2.getUrlString())
-    
     self.tic()
     upgrade_decision2 = computer.Computer_checkAndCreateUpgradeDecision()
+    self.assertEqual(len(upgrade_decision2), 0)
+  
+  def testComputer_checkAndCreateUpgradeDecision_with_exist(self):
+    person = self._makePerson(self.new_id)
+    computer = self._makeComputer(self.new_id)
+    computer.edit(source_administration_value=person)
+    software_product = self._makeSoftwareProduct(self.new_id)
+    software_release = self._requestSoftwareRelease(self.new_id,
+                                    software_product.getRelativeUrl())
+    self._makeSoftwareInstallation(self.new_id,
+                              computer, software_release.getUrlString())
+    self._requestSoftwareRelease(self.generateNewId(),
+                                      software_product.getRelativeUrl())
+    self.tic()
     
-    self.assertEqual(upgrade_decision2, None)
-
+    upgrade_decision = computer.Computer_checkAndCreateUpgradeDecision()[0]
+    self.assertEqual(upgrade_decision.getSimulationState(), 'confirmed')
+    
+    software_release3 = self._requestSoftwareRelease(self.generateNewId(),
+                                      software_product.getRelativeUrl())
+    self.tic()
+    
+    upgrade_decision2 = computer.Computer_checkAndCreateUpgradeDecision()[0]
+    
+    self.assertEqual(upgrade_decision.getSimulationState(), 'cancelled')
+    self.assertEqual(upgrade_decision2.getSimulationState(), 'confirmed')
+    release = upgrade_decision2.UpgradeDecision_getSoftwareRelease()
+    self.assertEqual(release.getUrlString(),
+                                software_release3.getUrlString())
+    
+  
   def testComputer_hostingSubscriptionCreateUpgradeDecision_no_newer(self):
     person = self._makePerson(self.new_id)
     computer = self._makeComputer(self.new_id)
@@ -717,7 +806,7 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
     self.tic()
     
     upgrade_decision = computer.Computer_hostingSubscriptionCreateUpgradeDecision()
-    self.assertEqual(upgrade_decision, None)
+    self.assertEqual(len(upgrade_decision), 0)
     
     # Create Hosting Subscription
     hosting_subscription = self._makeFullHostingSubscription(self.new_id,
@@ -725,7 +814,7 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
     self.tic()
     
     upgrade_decision = computer.Computer_hostingSubscriptionCreateUpgradeDecision()
-    self.assertEqual(upgrade_decision, None)
+    self.assertEqual(len(upgrade_decision), 0)
     
     self._makeFullSoftwareInstance(hosting_subscription, url_string)
     self._markComputerPartitionBusy(computer,
@@ -736,7 +825,7 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
     self.tic()
     
     upgrade_decision = computer.Computer_hostingSubscriptionCreateUpgradeDecision()
-    self.assertEqual(upgrade_decision, None)
+    self.assertEqual(len(upgrade_decision), 0)
   
   def testComputer_hostingSubscriptionCreateUpgradeDecision(self):
     person = self._makePerson(self.new_id)
@@ -760,359 +849,66 @@ class TestSlapOSPDMSkins(testSlapOSMixin):
     # Install the Newest software release
     software_release2 = self._requestSoftwareRelease(self.generateNewId(),
                                       software_product.getRelativeUrl())
-    self._makeSoftwareInstallation(self.new_id, computer,
+    self._makeSoftwareInstallation(self.generateNewId(), computer,
                                     software_release2.getUrlString())
     self.tic()
     
-    upgrade_decision = computer.Computer_hostingSubscriptionCreateUpgradeDecision()
-    self.assertEqual(upgrade_decision.getSimulationState(), 'confirmed')
+    up_decision = computer.Computer_hostingSubscriptionCreateUpgradeDecision()[0]
+    self.assertEqual(up_decision.getSimulationState(), 'confirmed')
     
-    self.assertEqual(upgrade_decision.UpgradeDecision_getHostingSubscription().\
+    self.assertEqual(up_decision.UpgradeDecision_getHostingSubscription().\
                       getReference(), hosting_subscription.getReference())
 
-    self.assertEqual(upgrade_decision.UpgradeDecision_getSoftwareRelease().\
+    self.assertEqual(up_decision.UpgradeDecision_getSoftwareRelease().\
                               getUrlString(), software_release2.getUrlString())
     
     self.tic()
-    upgrade_decision2 = computer.Computer_hostingSubscriptionCreateUpgradeDecision()
-    self.assertEqual(upgrade_decision2, None)
-
+    up_decision2 = computer.Computer_hostingSubscriptionCreateUpgradeDecision()
+    self.assertEqual(len(up_decision2), 0)
   
-  def testBase_acceptUpgradeDecision_no_reference(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    self.assertRaises(ValueError, self.portal.Base_acceptUpgradeDecision, None)
-    
-  def testBase_acceptUpgradeDecision_duplicated_reference(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTBADREFERENCE")
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTBADREFERENCE")
-    self.tic()
-    self.assertRaises(ValueError, self.portal.Base_acceptUpgradeDecision, None)
-
-  def testBase_acceptUpgradeDecision_no_upgrade_decision(self):
-    redirect_url = self.portal.Base_acceptUpgradeDecision('UD-UNEXISTING')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Unable%20to%20find%20the%20Upgrade%20Decision."), 
-      "%s contains the wrong message" %  redirect_url)
-     
-  def testBase_acceptUpgradeDecision_draft_upgrade_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTDRAFT")
-    self.tic()
-    redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTDRAFT')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Sorry%2C%20the%20upgrade%20is%20not%20possible%20yet%21"), 
-      "%s contains the wrong message" %  redirect_url)
-
-  def testBase_acceptUpgradeDecision_planned_upgrade_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTPLANNED")
-    upgrade_decision.plan()
-    self.tic()
-    redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTPLANNED')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Sorry%2C%20the%20upgrade%20is%20not%20possible%20yet%21"), 
-      "%s contains the wrong message" %  redirect_url)
-
-  def testBase_acceptUpgradeDecision_confirmed_upgrade_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTCONFIRMED")
-    upgrade_decision.confirm()
-    self.tic()
-    redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTCONFIRMED')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=This%20Upgrade%20Decision%20has%20been%20"\
-      "requested%2C%20it%20will%20be%20processed%20in%20few%20minutes."), 
-      "%s contains the wrong message" %  redirect_url)
-    self.assertEquals(upgrade_decision.getSimulationState(), 'started')
-
-  def testBase_acceptUpgradeDecision_started_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTSTARTED")
-    upgrade_decision.start()
-    self.tic()
-    redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTSTARTED')
-    self.assertTrue(redirect_url.endswith(
-     "?portal_status_message=This%20Upgrade%20Decision%20is%20already%20Started."), 
-     "%s contains the wrong message" %  redirect_url)
-
-  def testBase_acceptUpgradeDecision_stop_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTSTOP")
-    upgrade_decision.start()
-    upgrade_decision.stop()
-    self.tic()
-    redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTSTOP')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=This%20Upgrade%20Decision%20has%20been%20already%20processed."),
-      "%s contains the wrong message" %  redirect_url)
-
-  def testBase_acceptUpgradeDecision_delivered_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTDELIVERED")
-    upgrade_decision.start()
-    upgrade_decision.stop()
-    upgrade_decision.deliver()
-    self.tic()
-    redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTDELIVERED')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=This%20Upgrade%20Decision%20has%20been%20already%20processed."),
-      "%s contains the wrong message" %  redirect_url)
-
-  def testBase_acceptUpgradeDecision_cancelled_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTCANCELLED")
-    upgrade_decision.cancel()
-    self.tic()
-    redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTCANCELLED')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Sorry%2C%20the%20upgrade%20is%20not%20possble%2C%20Upgrade%20Decision%20was%20Canceled%20or%20Rejected%21"),
-      "%s contains the wrong message" %  redirect_url)
-
-  def testBase_acceptUpgradeDecision_rejected_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTREJECT")
-    upgrade_decision.cancel()
-    self.tic()
-    redirect_url = self.portal.Base_acceptUpgradeDecision('UD-TESTREJECT')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Sorry%2C%20the%20upgrade%20is%20not%20possble%2C%20Upgrade%20Decision%20was%20Canceled%20or%20Rejected%21"),
-      "%s contains the wrong message" %  redirect_url)
-
-  def testBase_rejectUpgradeDecision_no_reference(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    self.assertRaises(ValueError, self.portal.Base_rejectUpgradeDecision, None)
-    
-  def testBase_rejectUpgradeDecision_duplicated_reference(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTBADREFERENCE")
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTBADREFERENCE")
-    self.tic()
-    self.assertRaises(ValueError, self.portal.Base_acceptUpgradeDecision, None)
-
-  def testBase_rejectUpgradeDecision_no_upgrade_decision(self):
-    redirect_url = self.portal.Base_rejectUpgradeDecision('UD-UNEXISTING')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Unable%20to%20find%20the%20Upgrade%20Decision."), 
-      "%s contains the wrong message" %  redirect_url)
-     
-  def testBase_rejectUpgradeDecision_draft_upgrade_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTDRAFT")
-    self.tic()
-    redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTDRAFT')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Thanks%20Upgrade%20Decision%20has%20been"\
-      "%20rejected%20Successfully%20%28You%20cannot%20use%20it%20anymore%29."), 
-      "%s contains the wrong message" %  redirect_url)
-    self.assertEquals(upgrade_decision.getSimulationState(), 'rejected')
-
-  def testBase_rejectUpgradeDecision_planned_upgrade_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTPLANNED")
-    upgrade_decision.plan()
-    self.tic()
-    redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTPLANNED')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Thanks%20Upgrade%20Decision%20has%20been"\
-      "%20rejected%20Successfully%20%28You%20cannot%20use%20it%20anymore%29."), 
-      "%s contains the wrong message" %  redirect_url)
-    self.assertEquals(upgrade_decision.getSimulationState(), 'rejected')
-
-  def testBase_rejectUpgradeDecision_confirmed_upgrade_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTCONFIRMED")
-    upgrade_decision.confirm()
-    self.tic()
-    redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTCONFIRMED')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Thanks%20Upgrade%20Decision%20has%20been"\
-      "%20rejected%20Successfully%20%28You%20cannot%20use%20it%20anymore%29."),
-      "%s contains the wrong message" %  redirect_url)
-    self.assertEquals(upgrade_decision.getSimulationState(), 'rejected')
-
-  def testBase_rejectUpgradeDecision_started_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTSTARTED")
-    upgrade_decision.start()
-    self.tic()
-    redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTSTARTED')
-    self.assertTrue(redirect_url.endswith(
-     "?portal_status_message=Sorry%2C%20This%20Upgrade%20Decision%20is%20"\
-     "already%20Started%2C%20you%20cannot%20reject%20it%20anymore."),
-     "%s contains the wrong message" %  redirect_url)
-
-  def testBase_rejectUpgradeDecision_stop_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTSTOP")
-    upgrade_decision.start()
-    upgrade_decision.stop()
-    self.tic()
-    redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTSTOP')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Sorry%2C%20this%20Upgrade%20Decision%20has%20been%20already%20processed."),
-      "%s contains the wrong message" %  redirect_url)
-
-  def testBase_rejectUpgradeDecision_delivered_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTDELIVERED")
-    upgrade_decision.start()
-    upgrade_decision.stop()
-    upgrade_decision.deliver()
-    self.tic()
-    redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTDELIVERED')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Sorry%2C%20this%20Upgrade%20Decision%20has%20been%20already%20processed."),
-      "%s contains the wrong message" %  redirect_url)
-
-  def testBase_rejectUpgradeDecision_cancelled_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTCANCELLED")
-    upgrade_decision.cancel()
-    self.tic()
-    redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTCANCELLED')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Upgrade%20Decision%20is%20already%20Rejected%21"),
-      "%s contains the wrong message" %  redirect_url)
-
-  def testBase_rejectUpgradeDecision_reject_decision(self):
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.setReference("UD-TESTREJECT")
-    upgrade_decision.reject()
-    self.tic()
-    redirect_url = self.portal.Base_rejectUpgradeDecision('UD-TESTREJECT')
-    self.assertTrue(redirect_url.endswith(
-      "?portal_status_message=Upgrade%20Decision%20is%20already%20Rejected%21"),
-      "%s contains the wrong message" %  redirect_url)
-
-  @simulate('NotificationTool_getDocumentValue',
-            'reference=None',
-  'assert reference == "slapos-upgrade-computer.notification"\n' \
-  'return context.restrictedTraverse(' \
-  'context.REQUEST["testUpgradeDecision_notify_computer"])')
-  def testUpgradeDecision_notify_computer(self):
+  
+  def testComputer_hostingSubscriptionCreateUpgradeDecision_with_exist(self):
     person = self._makePerson(self.new_id)
     computer = self._makeComputer(self.new_id)
-    software_release = self._makeSoftwareRelease(self.new_id)
+    computer.edit(source_administration_value=person)
+    self._makeComputerPartitions(computer)
     software_product = self._makeSoftwareProduct(self.new_id)
-    software_release.setAggregateValue(software_product)
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.edit(destination_decision_value=person)
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList([software_release, computer])
-    
-    notification_message = self.portal.notification_message_module.newContent(
-      portal_type="Notification Message",
-      title='Test NM title %s' % self.new_id,
-      text_content_substitution_mapping_method_id=
-          "NotificationMessage_getSubstitutionMappingDictFromArgument",
-      text_content="""${software_product_title}
-${computer_title}
-${computer_reference}
-${software_release_name}
-${software_release_reference}
-${upgrade_accept_link}
-${upgrade_reject_link}
-${new_software_release_url}""",
-      content_type='text/html',
-      )
-    self.portal.REQUEST\
-        ['testUpgradeDecision_notify_computer'] = \
-        notification_message.getRelativeUrl()
-    
-    self.tic()
-    
-    self.assertEquals(None, upgrade_decision.UpgradeDecision_notify())
-    
-    upgrade_decision.plan()
-    
-    self.tic()
-    
-    self.assertEquals(None, upgrade_decision.UpgradeDecision_notify())
-    
-    self.tic()
+    software_release = self._requestSoftwareRelease(self.new_id,
+                                    software_product.getRelativeUrl())
+    url_string = software_release.getUrlString()
     
-    self.assertEquals(upgrade_decision.getSimulationState(), 'confirmed')
-    self.assertEquals(len(upgrade_decision.getFollowUpRelatedValueList()), 1)
-    event = upgrade_decision.getFollowUpRelatedValue()
+    self._makeSoftwareInstallation(self.new_id, computer, url_string)
     
-    self.assertEquals(event.getTitle(), 
-     "New Software available for Installation at %s" % computer.getTitle())
-     
-    self.assertEqual(event.getTextContent().splitlines(),
-      [software_product.getTitle(), computer.getTitle(), computer.getReference(),
-       software_release.getTitle(), software_release.getReference(), 
-       'Base_acceptUpgradeDecision?reference=%s' % upgrade_decision.getReference(),
-       'Base_rejectUpgradeDecision?reference=%s' % upgrade_decision.getReference(),
-       software_release.getUrlString()])
-      
-      
-    self.assertEquals(event.getSimulationState(), "delivered")
-
-  @simulate('NotificationTool_getDocumentValue',
-            'reference=None',
-  'assert reference == "slapos-upgrade-hosting-subscription.notification"\n' \
-  'return context.restrictedTraverse(' \
-  'context.REQUEST["testUpgradeDecision_notify_hosting_subscription"])')
-  def testUpgradeDecision_notify_hosting_subscription(self):
-    person = self._makePerson(self.new_id)
-    hosting_subscription = self._makeHostingSubscription(self.new_id)
-    software_release = self._makeSoftwareRelease(self.new_id)
-    software_product = self._makeSoftwareProduct(self.new_id)
-    software_release.setAggregateValue(software_product)
-    upgrade_decision = self._makeUpgradeDecision()
-    upgrade_decision.edit(destination_decision_value=person)
-    upgrade_decision_line = self._makeUpgradeDecisionLine(upgrade_decision)
-    upgrade_decision_line.setAggregateValueList([software_release, 
-                                                hosting_subscription])
-
-    old_url = hosting_subscription.getUrlString()
-
-    notification_message = self.portal.notification_message_module.newContent(
-      portal_type="Notification Message",
-      title='Test NM title %s' % self.new_id,
-      text_content_substitution_mapping_method_id=
-          "NotificationMessage_getSubstitutionMappingDictFromArgument",
-      text_content="""${software_product_title}
-${hosting_subscription_title}
-${old_software_release_url}
-${software_release_name}
-${software_release_reference}
-${upgrade_accept_link}
-${upgrade_reject_link}
-${new_software_release_url}""",
-      content_type='text/html',
-      )
-    self.portal.REQUEST\
-        ['testUpgradeDecision_notify_hosting_subscription'] = \
-        notification_message.getRelativeUrl()
+    # Create Hosting Subscription and Software Instance
+    hosting_subscription = self._makeFullHostingSubscription(self.new_id,
+                                    url_string, person)
+    self._makeFullSoftwareInstance(hosting_subscription, url_string)
+    self._markComputerPartitionBusy(computer,
+                                    hosting_subscription.getPredecessorValue())
     
+    # Install the Newest software release
+    software_release2 = self._requestSoftwareRelease(self.generateNewId(),
+                                      software_product.getRelativeUrl())
+    self._makeSoftwareInstallation(self.generateNewId(), computer,
+                                    software_release2.getUrlString())
     self.tic()
     
-    self.assertEquals(None, upgrade_decision.UpgradeDecision_notify())
-    
-    upgrade_decision.plan()
+    up_decision = computer.Computer_hostingSubscriptionCreateUpgradeDecision()[0]
+    self.assertEqual(up_decision.getSimulationState(), 'confirmed')
     
+    # Install the another software release
+    software_release3 = self._requestSoftwareRelease(self.generateNewId(),
+                                      software_product.getRelativeUrl())
+    self._makeSoftwareInstallation(self.generateNewId(), computer,
+                                    software_release3.getUrlString())
     self.tic()
     
-    self.assertEquals(None, upgrade_decision.UpgradeDecision_notify())
-    
-    self.tic()
+    up_decision2 = computer.Computer_hostingSubscriptionCreateUpgradeDecision()[0]
+    self.assertEqual(up_decision2.getSimulationState(), 'confirmed')
+    self.assertEqual(up_decision.getSimulationState(), 'cancelled')
+    release = up_decision2.UpgradeDecision_getSoftwareRelease()
+    self.assertEqual(release.getUrlString(),
+                                software_release3.getUrlString())
     
-    self.assertEquals(upgrade_decision.getSimulationState(), 'confirmed')
-    self.assertEquals(len(upgrade_decision.getFollowUpRelatedValueList()), 1)
-    event = upgrade_decision.getFollowUpRelatedValue()
     
-    self.assertEquals(event.getTitle(), 
-     "New Upgrade available for %s" % hosting_subscription.getTitle())
-     
-    self.assertEqual(event.getTextContent().splitlines(),
-      [software_product.getTitle(), hosting_subscription.getTitle(), 
-       old_url, software_release.getTitle(), software_release.getReference(), 
-       'Base_acceptUpgradeDecision?reference=%s' % upgrade_decision.getReference(),
-       'Base_rejectUpgradeDecision?reference=%s' % upgrade_decision.getReference(),
-       software_release.getUrlString()])
-
-    self.assertEquals(event.getSimulationState(), "delivered")
\ No newline at end of file
+    
\ No newline at end of file
diff --git a/master/bt5/slapos_pdm/bt/revision b/master/bt5/slapos_pdm/bt/revision
index 368f89ceef179cc546403ac0d5ef1d0e4b340447..d99e90eb9675f72290ba32fbf844c1cb45c72718 100644
--- a/master/bt5/slapos_pdm/bt/revision
+++ b/master/bt5/slapos_pdm/bt/revision
@@ -1 +1 @@
-28
\ No newline at end of file
+29
\ No newline at end of file