Update effects should execute in proper order

and only when update signal does not trigger a refresh
diff --git a/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/BaseOSGiImpl.java b/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/BaseOSGiImpl.java
index f9c658b..1f9a222 100644
--- a/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/BaseOSGiImpl.java
+++ b/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/BaseOSGiImpl.java
@@ -23,6 +23,7 @@
 
 import java.util.HashMap;
 import java.util.IdentityHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -259,13 +260,17 @@
 					}
 				},
 					() -> {
-						boolean refresh = terminator.update();
+						AtomicBoolean atomicBoolean = new AtomicBoolean();
 
-						if (!refresh) {
-							onUpdate.accept(t);
-						}
+						UpdateSupport.deferPublication(() -> {
+							if (!atomicBoolean.get()) {
+								onUpdate.accept(t);
+							}
+						});
 
-						return refresh;
+						atomicBoolean.set(terminator.update());
+
+						return atomicBoolean.get();
 					}
 				);
 
diff --git a/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationOSGiImpl.java b/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationOSGiImpl.java
index 2690c05..54698dc 100644
--- a/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationOSGiImpl.java
+++ b/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationOSGiImpl.java
@@ -96,7 +96,7 @@
 								atomicReference.set(configuration);
 							}
 							else {
-								if (!terminatorAtomicReference.get().update()) {
+								if (!UpdateSupport.sendUpdate(terminatorAtomicReference.get())) {
 									return;
 								}
 							}
diff --git a/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationsOSGiImpl.java b/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationsOSGiImpl.java
index d718560..d485c53 100644
--- a/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationsOSGiImpl.java
+++ b/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ConfigurationsOSGiImpl.java
@@ -95,7 +95,7 @@
 
 								OSGiResult osgiResult = terminators.get(pid);
 
-								if (osgiResult != null && !osgiResult.update()) {
+								if (osgiResult != null && !UpdateSupport.sendUpdate(osgiResult)) {
 									return;
 								}
 							}
diff --git a/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/EffectsOSGi.java b/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/EffectsOSGi.java
index ed6864a..8b87d38 100644
--- a/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/EffectsOSGi.java
+++ b/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/EffectsOSGi.java
@@ -19,6 +19,8 @@
 
 import org.apache.aries.component.dsl.OSGiResult;
 
+import java.util.concurrent.atomic.AtomicBoolean;
+
 /**
  * @author Carlos Sierra Andrés
  */
@@ -58,11 +60,18 @@
                         }
                     },
                     () -> {
-                        onUpdate.run();
+                        AtomicBoolean atomicBoolean = new AtomicBoolean();
 
-                        return terminator.update();
-                    }
-                );
+                        UpdateSupport.deferPublication(() -> {
+                            if (!atomicBoolean.get()) {
+                                onUpdate.run();
+                            }
+                        });
+
+                        atomicBoolean.set(terminator.update());
+
+                        return atomicBoolean.get();
+                    }                );
 
                 try {
                     onAddingAfter.run();
diff --git a/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ServiceReferenceOSGi.java b/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ServiceReferenceOSGi.java
index 998bbae..e60aa22 100644
--- a/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ServiceReferenceOSGi.java
+++ b/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/ServiceReferenceOSGi.java
@@ -74,7 +74,7 @@
 		public void modifiedService(
 			ServiceReference<T> reference, Tracked<T> tracked) {
 
-			if (tracked.runnable.update()) {
+			if (UpdateSupport.sendUpdate(tracked.runnable)) {
 				UpdateSupport.runUpdate(() -> {
 					tracked.runnable.run();
 					tracked.cachingServiceReference = new CachingServiceReference<>(
diff --git a/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/UpdateSupport.java b/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/UpdateSupport.java
index 253ca30..76bd163 100644
--- a/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/UpdateSupport.java
+++ b/component-dsl/src/main/java/org/apache/aries/component/dsl/internal/UpdateSupport.java
@@ -17,8 +17,11 @@
 
 package org.apache.aries.component.dsl.internal;
 
+import org.apache.aries.component.dsl.OSGiResult;
+
 import java.util.Deque;
 import java.util.LinkedList;
+import java.util.function.Supplier;
 
 /**
  * @author Carlos Sierra Andrés
@@ -55,6 +58,14 @@
     }
 
     public static void runUpdate(Runnable runnable) {
+        UpdateSupport.<Void>runInUpdate(() -> {runnable.run(); return null;});
+    }
+
+    public static boolean sendUpdate(OSGiResult osgiResult) {
+        return runInUpdate(osgiResult::update);
+    }
+
+    public static <R> R runInUpdate(Supplier<R> supplier) {
         isUpdate.set(true);
 
         Deque<Deque<Runnable>> deferredPublishers =
@@ -66,7 +77,7 @@
         deferredTerminators.addLast(new LinkedList<>());
 
         try {
-            runnable.run();
+            return supplier.get();
         }
         finally {
             isUpdate.set(false);
@@ -88,4 +99,5 @@
             isUpdate.set(!deferredTerminators.isEmpty());
         }
     }
+
 }
diff --git a/itests/src/main/java/org/apache/aries/component/dsl/test/DSLTest.java b/itests/src/main/java/org/apache/aries/component/dsl/test/DSLTest.java
index 875dc3a..f644a3c 100644
--- a/itests/src/main/java/org/apache/aries/component/dsl/test/DSLTest.java
+++ b/itests/src/main/java/org/apache/aries/component/dsl/test/DSLTest.java
@@ -2202,6 +2202,92 @@
 
         assertEquals(maps, gone);
     }
+
+    @Test
+    public void testUpdateEffectsOrder() {
+        ArrayList<String> updateEffects = new ArrayList<>();
+
+        ServiceRegistration<Service> serviceRegistration =
+            bundleContext.registerService(
+                Service.class, new Service(),
+                new Hashtable<String, Object>() {{
+                    put("property", "original");
+                }});
+
+        try {
+            OSGi<?> program =
+                serviceReferences(
+                    Service.class, __ -> false
+                ).effects(
+                    __ -> {},
+                    __ -> {},
+                    __ -> updateEffects.add("first")
+                ).effects(
+                    __ -> {},
+                    __ -> {},
+                    __ -> updateEffects.add("second")
+                );
+
+            program.run(bundleContext);
+
+            assertEquals(Collections.emptyList(), updateEffects);
+
+            serviceRegistration.setProperties(
+                new Hashtable<String, Object>() {{
+                    put("property", "updated");
+                }});
+
+            assertEquals(Arrays.asList("first", "second"), updateEffects);
+        }
+        finally {
+            serviceRegistration.unregister();
+        }
+    }
+
+    @Test
+    public void testUpdateEffectsAreOnlyExecutedWhenNoRefresh() {
+        ArrayList<String> updateEffects = new ArrayList<>();
+
+        ServiceRegistration<Service> serviceRegistration =
+            bundleContext.registerService(
+                Service.class, new Service(),
+                new Hashtable<String, Object>() {{
+                    put("property", "original");
+                }});
+
+        try {
+            OSGi<?> program =
+                refreshWhen(
+                    serviceReferences(
+                        Service.class, __ -> false
+                    ).effects(
+                        __ -> {},
+                        __ -> {},
+                        __ -> updateEffects.add("first")
+                    ).effects(
+                        __ -> {},
+                        __ -> {},
+                        __ -> updateEffects.add("second")
+                    ),
+                    __ -> true
+                );
+
+            program.run(bundleContext);
+
+            assertEquals(Collections.emptyList(), updateEffects);
+
+            serviceRegistration.setProperties(
+                new Hashtable<String, Object>() {{
+                    put("property", "updated");
+                }});
+
+            assertEquals(Collections.emptyList(), updateEffects);
+        }
+        finally {
+            serviceRegistration.unregister();
+        }
+    }
+
     static BundleContext bundleContext = FrameworkUtil.getBundle(
         DSLTest.class).getBundleContext();