[541803] Updates to the bundle pool cause launched installations to do
very expensive work

https://bugs.eclipse.org/bugs/show_bug.cgi?id=541803
diff --git a/features/org.eclipse.oomph.p2-feature/feature.xml b/features/org.eclipse.oomph.p2-feature/feature.xml
index ea4ae9d..1a65fea 100644
--- a/features/org.eclipse.oomph.p2-feature/feature.xml
+++ b/features/org.eclipse.oomph.p2-feature/feature.xml
@@ -12,7 +12,7 @@
 <feature
       id="org.eclipse.oomph.p2"
       label="%featureName"
-      version="1.10.0.qualifier"
+      version="1.11.0.qualifier"
       provider-name="%providerName"
       license-feature="org.eclipse.oomph.license"
       license-feature-version="0.0.0">
diff --git a/features/org.eclipse.oomph.p2-feature/pom.xml b/features/org.eclipse.oomph.p2-feature/pom.xml
index e2e71be..fd5592b 100644
--- a/features/org.eclipse.oomph.p2-feature/pom.xml
+++ b/features/org.eclipse.oomph.p2-feature/pom.xml
@@ -20,6 +20,6 @@
   </parent>
   <groupId>org.eclipse.oomph.features</groupId>
   <artifactId>org.eclipse.oomph.p2</artifactId>
-  <version>1.10.0-SNAPSHOT</version>
+  <version>1.11.0-SNAPSHOT</version>
   <packaging>eclipse-feature</packaging>
 </project>
diff --git a/plugins/org.eclipse.oomph.p2.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.p2.core/META-INF/MANIFEST.MF
index ef65078..3fa4776 100644
--- a/plugins/org.eclipse.oomph.p2.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.oomph.p2.core/META-INF/MANIFEST.MF
@@ -2,14 +2,14 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.oomph.p2.core;singleton:=true
-Bundle-Version: 1.10.0.qualifier
+Bundle-Version: 1.11.0.qualifier
 Bundle-ClassPath: .
 Bundle-Activator: org.eclipse.oomph.p2.internal.core.P2CorePlugin$Implementation
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.eclipse.oomph.p2.core;version="1.10.0";x-internal:=true,
- org.eclipse.oomph.p2.internal.core;version="1.10.0";x-internal:=true
+Export-Package: org.eclipse.oomph.p2.core;version="1.11.0";x-internal:=true,
+ org.eclipse.oomph.p2.internal.core;version="1.11.0";x-internal:=true
 Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.core.variables;bundle-version="[3.0.0,4.0.0)";resolution:=optional,
  org.eclipse.emf.ecore.xmi;bundle-version="[2.10.0,3.0.0)",
diff --git a/plugins/org.eclipse.oomph.p2.core/pom.xml b/plugins/org.eclipse.oomph.p2.core/pom.xml
index 4cac74d..f205c53 100644
--- a/plugins/org.eclipse.oomph.p2.core/pom.xml
+++ b/plugins/org.eclipse.oomph.p2.core/pom.xml
@@ -20,7 +20,7 @@
   </parent>
   <groupId>org.eclipse.oomph</groupId>
   <artifactId>org.eclipse.oomph.p2.core</artifactId>
-  <version>1.10.0-SNAPSHOT</version>
+  <version>1.11.0-SNAPSHOT</version>
   <packaging>eclipse-plugin</packaging>
 
   <build>
diff --git a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/P2Util.java b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/P2Util.java
index 84054f7..27cb81e 100644
--- a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/P2Util.java
+++ b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/core/P2Util.java
@@ -127,6 +127,30 @@
     return requirement instanceof org.eclipse.equinox.internal.p2.metadata.IRequiredCapability;
   }
 
+  public static Runnable preserveBundlePoolTimestamps(File bundlePoolLocation)
+  {
+    final File featuresFolder = new File(bundlePoolLocation, "features");
+    final long featuresFolderLastModified = featuresFolder.lastModified();
+    final File pluginsFolder = new File(bundlePoolLocation, "plugins");
+    final long pluginsFolderLastModified = pluginsFolder.lastModified();
+
+    return new Runnable()
+    {
+      public void run()
+      {
+        if (featuresFolderLastModified != 0L)
+        {
+          featuresFolder.setLastModified(featuresFolderLastModified);
+        }
+
+        if (pluginsFolderLastModified != 0L)
+        {
+          pluginsFolder.setLastModified(pluginsFolderLastModified);
+        }
+      }
+    };
+  }
+
   public static String getName(IInstallableUnit iu)
   {
     String name = iu.getProperty(IInstallableUnit.PROP_NAME, null);
diff --git a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/internal/core/AgentImpl.java b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/internal/core/AgentImpl.java
index c4b66e7..e38811a 100644
--- a/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/internal/core/AgentImpl.java
+++ b/plugins/org.eclipse.oomph.p2.core/src/org/eclipse/oomph/p2/internal/core/AgentImpl.java
@@ -28,7 +28,10 @@
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Platform;
+import org.eclipse.equinox.internal.p2.engine.BeginOperationEvent;
 import org.eclipse.equinox.internal.p2.engine.CommitOperationEvent;
+import org.eclipse.equinox.internal.p2.engine.RollbackOperationEvent;
+import org.eclipse.equinox.internal.p2.engine.TransactionEvent;
 import org.eclipse.equinox.internal.p2.repository.Transport;
 import org.eclipse.equinox.internal.p2.touchpoint.eclipse.EclipseTouchpoint;
 import org.eclipse.equinox.internal.p2.touchpoint.eclipse.Util;
@@ -522,16 +525,46 @@
       {
         eventBus.addListener(new SynchronousProvisioningListener()
         {
+          private Runnable restoreBundlePoolTimestamps;
+
           public void notify(EventObject event)
           {
-            if (event instanceof CommitOperationEvent)
+            if (event instanceof TransactionEvent)
             {
-              CommitOperationEvent commitOperationEvent = (CommitOperationEvent)event;
-              IProfile profile = commitOperationEvent.getProfile();
-              if (Profile.TYPE_INSTALLATION.equals(profile.getProperty(Profile.PROP_PROFILE_TYPE)))
+              TransactionEvent transactionEvent = (TransactionEvent)event;
+              IProfile profile = transactionEvent.getProfile();
+              if ("true".equals(profile.getProperty(Profile.PROP_PROFILE_SHARED_POOL)))
               {
-                // If this is a commit of an Oomph-created installation profile, then adjust the installation details.
-                adjustInstallation(profile);
+                String cache = profile.getProperty(IProfile.PROP_CACHE);
+                if (cache != null)
+                {
+                  File bundlePoolLocation = new File(cache).getAbsoluteFile();
+                  if (bundlePoolLocation.exists())
+                  {
+                    if (event instanceof BeginOperationEvent)
+                    {
+                      // Remember the time stamps of these folders before we start.
+                      restoreBundlePoolTimestamps = P2Util.preserveBundlePoolTimestamps(bundlePoolLocation);
+                    }
+                    else if (event instanceof CommitOperationEvent || event instanceof RollbackOperationEvent)
+                    {
+                      // Restore the time stamps of these folders after we finish regardless of either success or failure.
+                      if (restoreBundlePoolTimestamps != null)
+                      {
+                        restoreBundlePoolTimestamps.run();
+                      }
+                    }
+                  }
+                }
+              }
+
+              if (event instanceof CommitOperationEvent)
+              {
+                if (Profile.TYPE_INSTALLATION.equals(profile.getProperty(Profile.PROP_PROFILE_TYPE)))
+                {
+                  // If this is a commit of an Oomph-created installation profile, then adjust the installation details.
+                  adjustInstallation(profile);
+                }
               }
             }
           }
diff --git a/plugins/org.eclipse.oomph.setup.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.core/META-INF/MANIFEST.MF
index 5183d35..c6612f6 100644
--- a/plugins/org.eclipse.oomph.setup.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.oomph.setup.core/META-INF/MANIFEST.MF
@@ -32,7 +32,7 @@
  org.eclipse.equinox.p2.updatesite;bundle-version="[1.0.0,2.0.0)",
  org.eclipse.equinox.security;bundle-version="[1.0.0,2.0.0)",
  org.eclipse.oomph.base.edit;bundle-version="[1.10.0,2.0.0)",
- org.eclipse.oomph.p2.core;bundle-version="[1.10.0,2.0.0)",
+ org.eclipse.oomph.p2.core;bundle-version="[1.11.0,2.0.0)",
  org.eclipse.oomph.setup;bundle-version="[1.10.0,2.0.0)";visibility:=reexport,
  org.eclipse.oomph.setup.p2;bundle-version="[1.10.0,2.0.0)",
  org.eclipse.oomph.preferences;bundle-version="[1.10.0,2.0.0)",
diff --git a/plugins/org.eclipse.oomph.setup.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.setup.ui/META-INF/MANIFEST.MF
index be14115..d867131 100644
--- a/plugins/org.eclipse.oomph.setup.ui/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.oomph.setup.ui/META-INF/MANIFEST.MF
@@ -32,7 +32,7 @@
  org.eclipse.oomph.setup.sync;bundle-version="[1.10.0,2.0.0)",
  org.eclipse.oomph.ui;bundle-version="[1.10.0,2.0.0)",
  org.eclipse.oomph.p2.edit;bundle-version="[1.10.0,2.0.0)";visibility:=reexport,
- org.eclipse.oomph.p2.core;bundle-version="[1.10.0,2.0.0)",
+ org.eclipse.oomph.p2.core;bundle-version="[1.11.0,2.0.0)",
  org.eclipse.oomph.p2.ui;bundle-version="[1.10.0,2.0.0)",
  org.eclipse.oomph.jreinfo.ui;bundle-version="[1.10.0,2.0.0)",
  org.eclipse.oomph.preferences;bundle-version="[1.10.0,2.0.0)"
diff --git a/plugins/org.eclipse.oomph.targlets.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.oomph.targlets.core/META-INF/MANIFEST.MF
index dfd7cff..544c40b 100644
--- a/plugins/org.eclipse.oomph.targlets.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.oomph.targlets.core/META-INF/MANIFEST.MF
@@ -28,7 +28,7 @@
  org.eclipse.jdt.core;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.pde.core;bundle-version="[3.5.0,4.0.0)",
  org.eclipse.oomph.targlets;bundle-version="[1.10.0,2.0.0)";visibility:=reexport,
- org.eclipse.oomph.p2.core;bundle-version="[1.10.0,2.0.0)";visibility:=reexport,
+ org.eclipse.oomph.p2.core;bundle-version="[1.11.0,2.0.0)";visibility:=reexport,
  org.eclipse.oomph.util.pde;bundle-version="[1.10.0,2.0.0)",
  org.eclipse.equinox.frameworkadmin;bundle-version="[2.0.0,3.0.0)"
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/org.eclipse.oomph.targlets.core/src/org/eclipse/oomph/targlets/internal/core/TargletContainerDescriptor.java b/plugins/org.eclipse.oomph.targlets.core/src/org/eclipse/oomph/targlets/internal/core/TargletContainerDescriptor.java
index 615164a..6fa30c1 100644
--- a/plugins/org.eclipse.oomph.targlets.core/src/org/eclipse/oomph/targlets/internal/core/TargletContainerDescriptor.java
+++ b/plugins/org.eclipse.oomph.targlets.core/src/org/eclipse/oomph/targlets/internal/core/TargletContainerDescriptor.java
@@ -71,6 +71,8 @@
 
   private transient Profile transactionProfile;
 
+  private transient Runnable restoreBundlePoolTimestamps;
+
   public TargletContainerDescriptor()
   {
   }
@@ -276,6 +278,7 @@
     }
 
     transactionProfile = getOrCreateProfile(id, poolLocation, environmentProperties, nlProperty, digest, monitor);
+    restoreBundlePoolTimestamps = P2Util.preserveBundlePoolTimestamps(poolLocation);
     return transactionProfile;
   }
 
@@ -286,6 +289,12 @@
       throw new ProvisionException("No update transaction is ongoing");
     }
 
+    if (restoreBundlePoolTimestamps != null)
+    {
+      restoreBundlePoolTimestamps.run();
+      restoreBundlePoolTimestamps = null;
+    }
+
     transactionProfile = null;
     workingDigest = digest;
     workingProjects = workspaceIUInfos;
@@ -296,6 +305,12 @@
 
   void rollbackUpdateTransaction(Throwable t, IProgressMonitor monitor) throws CoreException
   {
+    if (restoreBundlePoolTimestamps != null)
+    {
+      restoreBundlePoolTimestamps.run();
+      restoreBundlePoolTimestamps = null;
+    }
+
     transactionProfile = null;
 
     if (t != null)