diff --git a/Gaudi/doc/release.notes b/Gaudi/doc/release.notes
index 233fc0e05afe0c0996f3974de70e4966b6c420bc..85084e2f087970931988e0060288c2fd456a9b57 100644
--- a/Gaudi/doc/release.notes
+++ b/Gaudi/doc/release.notes
@@ -1,6 +1,15 @@
 Package : Gaudi
 Package manager : Marco Clemencic
 
+! 2014-02-06 - Marco Clemencic
+ - Improved test gaudi.conf_user.autoapply to be more robust in case of a change
+   in the order of application of configurables.
+
+! 2014-02-06 - Marco Clemencic
+ - Added test exposing bug #103803:
+   ConfigurableUser instances created in the __apply_configuration__ of another
+   one are not "applied".
+
 ! 2013-12-11 - Sebastien Binet
  - Added hwaf configuration files.
 
diff --git a/Gaudi/tests/qmtest/gaudi.qms/conf_user.qms/autoapply.qmt b/Gaudi/tests/qmtest/gaudi.qms/conf_user.qms/autoapply.qmt
new file mode 100644
index 0000000000000000000000000000000000000000..4fabe0f9cff634283fccd542766150887189ef4d
--- /dev/null
+++ b/Gaudi/tests/qmtest/gaudi.qms/conf_user.qms/autoapply.qmt
@@ -0,0 +1,5 @@
+<?xml version="1.0" ?>
+<!DOCTYPE extension  PUBLIC '-//QM/2.3/Extension//EN'  'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
+<extension class="GaudiTest.GaudiExeTest" kind="test">
+<argument name="program"><text>../scripts/test_configurable_users.py</text></argument>
+</extension>
diff --git a/Gaudi/tests/qmtest/gaudi.qms/conf_user.qms/delayed_creation.qmt b/Gaudi/tests/qmtest/gaudi.qms/conf_user.qms/delayed_creation.qmt
new file mode 100644
index 0000000000000000000000000000000000000000..560fddc2f6e966a5fe2ea74e40c5824bd44e928a
--- /dev/null
+++ b/Gaudi/tests/qmtest/gaudi.qms/conf_user.qms/delayed_creation.qmt
@@ -0,0 +1,5 @@
+<?xml version="1.0" ?>
+<!DOCTYPE extension  PUBLIC '-//QM/2.3/Extension//EN'  'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
+<extension class="GaudiTest.GaudiExeTest" kind="test">
+<argument name="program"><text>../scripts/test_cu_delayed_creation.py</text></argument>
+</extension>
diff --git a/Gaudi/tests/qmtest/gaudi.qms/conf_user_passive_dep.qmt b/Gaudi/tests/qmtest/gaudi.qms/conf_user.qms/passive_dep.qmt
similarity index 100%
rename from Gaudi/tests/qmtest/gaudi.qms/conf_user_passive_dep.qmt
rename to Gaudi/tests/qmtest/gaudi.qms/conf_user.qms/passive_dep.qmt
diff --git a/Gaudi/tests/qmtest/gaudi.qms/conf_user_autoapply.qmt b/Gaudi/tests/qmtest/gaudi.qms/conf_user_autoapply.qmt
deleted file mode 100644
index 0654948433569e7f515dfbf420718c8e7f082555..0000000000000000000000000000000000000000
--- a/Gaudi/tests/qmtest/gaudi.qms/conf_user_autoapply.qmt
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" ?>
-<!DOCTYPE extension  PUBLIC '-//QM/2.3/Extension//EN'  'http://www.codesourcery.com/qm/dtds/2.3/-//qm/2.3/extension//en.dtd'>
-<extension class="GaudiTest.GaudiExeTest" kind="test">
-<argument name="program"><text>../scripts/test_configurable_users.py</text></argument>
-<argument name="validator"><text>
-findReferenceBlock("""
-Applying Application
-/***** User Application/Application ****************************************************************
-|-Property1 = 10
-\----- (End of User Application/Application) -------------------------------------------------------
-Applying TestInstance
-/***** User MultiInstance/TestInstance *************************************************************
-|-Property = 1  (default: 0)
-\----- (End of User MultiInstance/TestInstance) ----------------------------------------------------
-Applying Application_MultiInstance
-/***** User MultiInstance/Application_MultiInstance ************************************************
-|-Property = 0
-\----- (End of User MultiInstance/Application_MultiInstance) ---------------------------------------
-Applying SubModule1
-/***** User SubModule1/SubModule1 ******************************************************************
-|-Property1 = 10  (default: 0)
-\----- (End of User SubModule1/SubModule1) ---------------------------------------------------------
-Applying SubModule2
-/***** User SubModule2/SubModule2 ******************************************************************
-|-Property1 = 10  (default: 2)
-\----- (End of User SubModule2/SubModule2) ---------------------------------------------------------
-Applying TestInstance_SubModule1
-/***** User SubModule1/TestInstance_SubModule1 *****************************************************
-|-Property1 = 0
-\----- (End of User SubModule1/TestInstance_SubModule1) --------------------------------------------
-Applying Application_MultiInstance_SubModule1
-/***** User SubModule1/Application_MultiInstance_SubModule1 ****************************************
-|-Property1 = 0
-\----- (End of User SubModule1/Application_MultiInstance_SubModule1) -------------------------------
-Action Object One
-Action Function
-Action Object Two
-Done.
-""")
-</text></argument>
-</extension>
diff --git a/Gaudi/tests/scripts/test_configurable_users.py b/Gaudi/tests/scripts/test_configurable_users.py
index 83b5ba2dfa6a35b0af7fcba285087f7c338ce7a4..4e92201b2e94ed120e4b89ad1483535a5a15b181 100755
--- a/Gaudi/tests/scripts/test_configurable_users.py
+++ b/Gaudi/tests/scripts/test_configurable_users.py
@@ -1,39 +1,37 @@
 from Gaudi.Configuration import *
 
-class SubModule1(ConfigurableUser):
-    __slots__ = { "Property1": 0 }
+appliedConf = []
+
+class ConfigurableUserTest(ConfigurableUser):
+    __slots__ = {}
     def __apply_configuration__(self):
         print "Applying", self.getName()
         print self
+        appliedConf.append(self.getName())
+
+class SubModule1(ConfigurableUserTest):
+    __slots__ = { "Property1": 0 }
 
-class SubModule2(ConfigurableUser):
+class SubModule2(ConfigurableUserTest):
     __slots__ = { "Property1": 2 }
-    def __apply_configuration__(self):
-        print "Applying", self.getName()
-        print self
 
-class SubModule3(ConfigurableUser):
+class SubModule3(ConfigurableUserTest):
     __slots__ = { "Property1": 3 }
-    def __apply_configuration__(self):
-        print "Applying", self.getName()
-        print self
 
-class MultiInstance(ConfigurableUser):
+class MultiInstance(ConfigurableUserTest):
     __slots__ = { "Property": 0 }
     __used_configurables__ = [ (SubModule1, None) ]
     def __apply_configuration__(self):
-        print "Applying", self.getName()
-        print self
+        super(MultiInstance, self).__apply_configuration__()
         SubModule1(self._instanceName(SubModule1))
 
-class Application(ConfigurableUser):
+class Application(ConfigurableUserTest):
     __slots__ = { "Property1": 10 }
     __used_configurables__ = [ SubModule1, SubModule2, SubModule3,
                                (MultiInstance, None), (MultiInstance, "TestInstance") ]
     def __apply_configuration__(self):
-        print "Applying", self.getName()
-        print self
-        if hasattr(self,"Property1"):
+        super(Application, self).__apply_configuration__()
+        if hasattr(self, "Property1"):
             val = self.Property1
         else:
             val = self.getDefaultProperty("Property1")
@@ -44,13 +42,17 @@ class Application(ConfigurableUser):
         ti = self.getUsedInstance("TestInstance")
         ti.Property = 1
 
+calledActions = []
+
 class Action(object):
     def __init__(self, msg):
         self.msg = msg
     def __call__(self):
+        calledActions.append(self.msg)
         print self.msg
 
 def ActionFunction():
+    calledActions.append("Action Function")
     print "Action Function"
 
 appendPostConfigAction(Action("Action Object One"))
@@ -63,4 +65,34 @@ Application()
 # apply all ConfigurableUser instances
 from GaudiKernel.Configurable import applyConfigurableUsers
 applyConfigurableUsers()
-print "Done."
+
+# check that everything has been applied
+expected = {'Application':               ('Property1', 10),
+            'TestInstance':              ('Property', 1),
+            'Application_MultiInstance': ('Property', 0),
+            'SubModule1':                ('Property1', 10),
+            'SubModule2':                ('Property1', 10),
+            'TestInstance_SubModule1':   ('Property1', 0),
+            'Application_MultiInstance_SubModule1': ('Property1', 0)}
+assert set(appliedConf) == set(expected)
+
+# check the order of application
+assert appliedConf.index('Application') < appliedConf.index('SubModule1')
+assert appliedConf.index('Application') < appliedConf.index('SubModule2')
+assert appliedConf.index('Application') < appliedConf.index('Application_MultiInstance')
+assert appliedConf.index('Application') < appliedConf.index('TestInstance')
+
+assert appliedConf.index('TestInstance') < appliedConf.index('TestInstance_SubModule1')
+
+assert appliedConf.index('Application_MultiInstance') < appliedConf.index('Application_MultiInstance_SubModule1')
+
+# check that the actions has been called in the right order
+expectedActions = ["Action Object One", "Action Function", "Action Object Two"]
+assert calledActions == expectedActions
+
+# check property values
+allConfs = Configurable.allConfigurables
+for name, (prop, value) in expected.items():
+    assert allConfs[name].getProp(prop) == value, "%s.%s != %s" % (name, prop, value)
+
+print "Success."
diff --git a/Gaudi/tests/scripts/test_cu_delayed_creation.py b/Gaudi/tests/scripts/test_cu_delayed_creation.py
new file mode 100755
index 0000000000000000000000000000000000000000..b41bdf3b7adf67085ce895268324d81522fbb158
--- /dev/null
+++ b/Gaudi/tests/scripts/test_cu_delayed_creation.py
@@ -0,0 +1,32 @@
+from Gaudi.Configuration import *
+
+class DelayedInstance(ConfigurableUser):
+    __slots__ = { "Property": 0,
+                  "Applied": False }
+    def __apply_configuration__(self):
+        print "Applying", self.getName()
+        print self
+        self.Applied = True
+
+class Application(ConfigurableUser):
+    __slots__ = { "Property": 10,
+                  "Applied": False }
+    __used_configurables__ = []
+    def __apply_configuration__(self):
+        print "Applying", self.getName()
+        print self
+        self.Applied = True
+        # This is instantiated late
+        DelayedInstance()
+
+# Instantiate the application configurable
+Application()
+
+# apply all ConfigurableUser instances
+from GaudiKernel.Configurable import applyConfigurableUsers
+applyConfigurableUsers()
+
+assert Application().Applied
+assert DelayedInstance().Applied
+
+print "Done."
diff --git a/GaudiKernel/doc/release.notes b/GaudiKernel/doc/release.notes
index 2c6047ab112b7b0d63816a5ee1bc514c076e4451..037d9a5863838fce66f0240b3a656e35e95a9c84 100644
--- a/GaudiKernel/doc/release.notes
+++ b/GaudiKernel/doc/release.notes
@@ -1,9 +1,12 @@
 Package : GaudiKernel
 Package manager : Marco Clemencic
 
+! 2014-02-06 - Marco Clemencic
+ - Fixed bug #103803: handle correctly ConfUsers created during the apply step.
+
 ! 2014-02-03 - Marco Clemencic
  - Do not generate configurables for the factory aliases used for backward
-   compatibility with the Reflex Plugin Service. 
+   compatibility with the Reflex Plugin Service.
 
 ! 2014-01-31 - Marco Clemencic
  - Replaced non-ASCII characters in string literals with the corresponding
diff --git a/GaudiKernel/python/GaudiKernel/Configurable.py b/GaudiKernel/python/GaudiKernel/Configurable.py
index 33a14d77067cc4e81591b2b3d555c0c170fb9a7a..ea5d90acea53f02ec4cde38f9ff761048c6430ab 100644
--- a/GaudiKernel/python/GaudiKernel/Configurable.py
+++ b/GaudiKernel/python/GaudiKernel/Configurable.py
@@ -909,6 +909,14 @@ class Configurable( object ):
         rep += Configurable._printFooter( indentStr, title )
         return rep
 
+    def isApplicable(self):
+        '''
+        Return True is the instance can be "applied".
+        Always False for plain Configurable instances
+        (i.e. not ConfigurableUser).
+        '''
+        return False
+
 ### classes for generic Gaudi component ===========
 class DummyDescriptor( object ):
     def __init__( self, name ):
@@ -1112,7 +1120,8 @@ class ConfigurableAuditor( Configurable ):
 class ConfigurableUser( Configurable ):
     __slots__ = { "__users__": [],
                   "__used_instances__": [],
-                  "_enabled": True }
+                  "_enabled": True,
+                  "_applied": False }
     ## list of ConfigurableUser classes this one is going to modify in the
     #  __apply_configuration__ method.
     #  The list may contain class objects, strings representing class objects or
@@ -1131,6 +1140,7 @@ class ConfigurableUser( Configurable ):
             setattr(self, n, v)
         self._enabled = _enabled
         self.__users__ = []
+        self._applied = False
 
         # Needed to retrieve the actual class if the declaration in __used_configurables__
         # and  __queried_configurables__ is done with strings.
@@ -1304,6 +1314,13 @@ class ConfigurableUser( Configurable ):
                 return i
         raise KeyError(name)
 
+    def isApplicable(self):
+        '''
+        Return True is the instance can be "applied".
+        '''
+        return (not self.__users__) and self._enabled and not self._applied
+
+
 # list of callables to be called after all the __apply_configuration__ are called.
 postConfigActions = []
 def appendPostConfigAction(function):
@@ -1319,7 +1336,7 @@ def appendPostConfigAction(function):
     postConfigActions.append(function)
 def removePostConfigAction(function):
     """
-    Remove a collable from the list of post-config actions.
+    Remove a callable from the list of post-config actions.
     The list is directly accessible as 'GaudiKernel.Configurable.postConfigActions'.
     """
     postConfigActions.remove(function)
@@ -1337,36 +1354,42 @@ def applyConfigurableUsers():
         return
     _appliedConfigurableUsers_ = True
 
-    confUsers = [ c
-                  for c in Configurable.allConfigurables.values()
-                  if hasattr(c,"__apply_configuration__") ]
-    applied = True # needed to detect dependency loops
-    while applied and confUsers:
-        newConfUsers = [] # list of conf users that cannot be applied yet
-        applied = False
-        for c in confUsers:
-            if hasattr(c,"__users__") and c.__users__:
-                newConfUsers.append(c) # cannot use this one yet
-            else: # it does not have users or the list is empty
-                applied = True
-                # the ConfigurableUser is enabled if it doesn't have an _enabled
-                # property or its value is True
-                enabled = (not hasattr(c, "_enabled")) or c._enabled
-                if enabled:
-                    log.info("applying configuration of %s", c.name())
-                    c.__apply_configuration__()
-                    log.info(c)
-                else:
-                    log.info("skipping configuration of %s", c.name())
-                if hasattr(c, "__detach_used__"):
-                    # tells the used configurables that they are not needed anymore
-                    c.__detach_used__()
-        confUsers = newConfUsers # list of C.U.s still to go
-    if confUsers:
-        # this means that some C.U.s could not be applied because of a dependency loop
-        raise Error("Detected loop in the ConfigurableUser "
+    def applicableConfUsers():
+        '''
+        Generator returning all the configurables that can be applied in the
+        order in which they can be applied.
+        '''
+        # This is tricky...
+        # We keep on looking for the first configurable that can be applied.
+        # When we cannot find any, 'next()' raises a StopIteration that is
+        # propagated outside of the infinite loop and the function, then handled
+        # correctly from outside (it is the exception that is raised when you
+        # exit from a generator).
+        # Checking every time the full list is inefficient, but it is the
+        # easiest way to fix bug #103803.
+        # <https://savannah.cern.ch/bugs/?103803>
+        while True:
+            yield (c for c in Configurable.allConfigurables.values()
+                   if c.isApplicable()).next()
+
+    for c in applicableConfUsers():
+        log.info("applying configuration of %s", c.name())
+        c.__apply_configuration__()
+        c._applied = True # flag the instance as already applied
+        log.info(c)
+        if hasattr(c, "__detach_used__"):
+            # tells the used configurables that they are not needed anymore
+            c.__detach_used__()
+
+    # check for dependency loops
+    leftConfUsers = [c for c in Configurable.allConfigurables.values()
+                     if hasattr(c, '__apply_configuration__') and
+                        c._enabled and not c._applied]
+    # if an enabled configurable has not been applied, there must be a dependency loop
+    if leftConfUsers:
+        raise Error("Detected loop in the ConfigurableUser"
                     " dependencies: %r" % [ c.name()
-                                            for c in confUsers ])
+                                            for c in leftConfUsers ])
     # ensure that all the Handles have been triggered
     known = set()
     unknown = set(Configurable.allConfigurables)