diff --git a/openbis/resource/test-data/core-plugins/plugin-X/15/core-plugin.properties b/openbis/resource/test-data/core-plugins/plugin-X/15/core-plugin.properties
new file mode 100644
index 0000000000000000000000000000000000000000..b0f26ef92681f4b1c868c7cb781e48552a39254a
--- /dev/null
+++ b/openbis/resource/test-data/core-plugins/plugin-X/15/core-plugin.properties
@@ -0,0 +1 @@
+required-plugins = plugin-Y:drop-boxes
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/coreplugin/CorePluginRegistrator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/coreplugin/CorePluginRegistrator.java
index d1a16c5be3608ccba9af71f03d33721cae8842f7..a537a876049a8f8788258b5ed4ae668a1fc46b3d 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/coreplugin/CorePluginRegistrator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/coreplugin/CorePluginRegistrator.java
@@ -60,22 +60,19 @@ public class CorePluginRegistrator implements InitializingBean
         CorePluginScanner pluginScanner = new CorePluginScanner(pluginsFolderName, ScannerType.AS);
         String sessionToken = getSessionToken();
         List<CorePlugin> plugins = pluginScanner.scanForPlugins();
-        for (CorePlugin plugin : moduleEnabledChecker.getListOfEnabledPlugins(plugins))
+        for (CorePlugin plugin : moduleEnabledChecker.getModuleWithEnabledMasterDataInitializations(plugins))
         {
-            if (moduleEnabledChecker.isModuleEnabled(plugin.getName()))
+            if (disabledMasterDataInitializationChecker.isModuleEnabled(plugin.getName()))
             {
-                if (disabledMasterDataInitializationChecker.isModuleEnabled(plugin.getName()))
+                operationLog.info("Registering of master data for plugin " + plugin + " is disabled");
+            } else
+            {
+                try
                 {
-                    operationLog.info("Registering of master data for plugin " + plugin + " is disabled");
-                } else
+                    commonServer.registerPlugin(sessionToken, plugin, pluginScanner);
+                } catch (Exception ex)
                 {
-                    try
-                    {
-                        commonServer.registerPlugin(sessionToken, plugin, pluginScanner);
-                    } catch (Exception ex)
-                    {
-                        operationLog.error("Failed to install core plugin: " + plugin, ex);
-                    }
+                    operationLog.error("Failed to install core plugin: " + plugin, ex);
                 }
             }
         }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/CorePlugin.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/CorePlugin.java
index 08fd4fc298e8315260064710b5c914f1df4d1bd4..6d67edb26726710968fa2194a7afb6eedb7a60b3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/CorePlugin.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/CorePlugin.java
@@ -16,6 +16,9 @@
 
 package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Represents a versioned openBIS core plugin.
  * 
@@ -27,6 +30,8 @@ public class CorePlugin implements Comparable<CorePlugin>
 
     private final int version;
 
+    private final List<String> requiredPlugins = new ArrayList<>();
+
     public CorePlugin(String name, int version)
     {
         this.name = name;
@@ -43,6 +48,16 @@ public class CorePlugin implements Comparable<CorePlugin>
         return version;
     }
 
+    public void addRequiredPlugin(String requiredPlugin)
+    {
+        requiredPlugins.add(requiredPlugin);
+    }
+
+    public List<String> getRequiredPlugins()
+    {
+        return requiredPlugins;
+    }
+
     @Override
     public int compareTo(CorePlugin other)
     {
@@ -57,7 +72,13 @@ public class CorePlugin implements Comparable<CorePlugin>
     @Override
     public String toString()
     {
-        return String.format("Core Plugin[name='%s', version='%s']", name, version);
+        if (requiredPlugins.isEmpty())
+        {
+            return String.format("Core Plugin[name='%s', version='%s']", name, version);
+        }
+        return String.format("Core Plugin[name='%s', version='%s', required plugins:%s]",
+                name, version, requiredPlugins);
+
     }
 
     @Override
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginScanner.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginScanner.java
index 323c2634c8234ec66e0b3c53f51a818d44306db7..86a6d31fd1254cf89825aae1ad119f200ca08a29 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginScanner.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginScanner.java
@@ -21,9 +21,11 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Properties;
 
 import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
 import ch.systemsx.cisd.common.filesystem.FileUtilities;
+import ch.systemsx.cisd.common.io.PropertyIOUtils;
 import ch.systemsx.cisd.common.logging.ISimpleLogger;
 import ch.systemsx.cisd.common.logging.Log4jSimpleLogger;
 import ch.systemsx.cisd.common.logging.LogCategory;
@@ -39,6 +41,10 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CorePlugin;
  */
 public class CorePluginScanner implements ICorePluginResourceLoader
 {
+    static final String CORE_PLUGIN_PROPERTIES_FILE_NAME = "core-plugin.properties";
+
+    static final String REQUIRED_PLUGINS_KEY = "required-plugins";
+    
     /**
      * the type of plugins we are scanning for.
      */
@@ -188,8 +194,18 @@ public class CorePluginScanner implements ICorePluginResourceLoader
     {
         String name = pluginDir.getName();
         int version = parseVersion(versionDir);
+        CorePlugin corePlugin = new CorePlugin(name, version);
+        File corePluginPropertiesFile = new File(versionDir, CORE_PLUGIN_PROPERTIES_FILE_NAME);
+        if (corePluginPropertiesFile.isFile())
+        {
+            Properties corePluginProperties = PropertyIOUtils.loadProperties(corePluginPropertiesFile);
+            for (String requiredPlugin : corePluginProperties.getProperty(REQUIRED_PLUGINS_KEY, "").split(","))
+            {
+                corePlugin.addRequiredPlugin(requiredPlugin.trim());
+            }
+        }
 
-        return new CorePlugin(name, version);
+        return corePlugin;
     }
 
     /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjector.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjector.java
index 1b0ea8c78a86b22208645090a9f25754b5f10c41..cee11217cb9bfdd85fdefdca6cf99fe7b5384ffd 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjector.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjector.java
@@ -122,7 +122,8 @@ public class CorePluginsInjector
                 scanForCorePlugins(corePluginsFolderPath, moduleEnabledChecker, disabledPlugins,
                         pluginNames, listOfDisabledMasterDataInitialization);
 
-        injectProperty(properties, Constants.DISABLED_MASTER_DATA_INITIALIZATION, StringUtils.join(listOfDisabledMasterDataInitialization, ","));
+        injectProperty(properties, Constants.DISABLED_MASTER_DATA_INITIALIZATION, 
+                StringUtils.join(listOfDisabledMasterDataInitialization, ","));
 
         for (Entry<IPluginType, Map<String, NamedCorePluginFolder>> entry : plugins.entrySet())
         {
@@ -168,7 +169,11 @@ public class CorePluginsInjector
             }
         }
         pluginKeyBundles.addOrReplaceKeyBundleIn(properties);
+        return createPluginFoldersMap(plugins);
+    }
 
+    private Map<String, File> createPluginFoldersMap(Map<IPluginType, Map<String, NamedCorePluginFolder>> plugins)
+    {
         Map<String, File> pluginFolders = new HashMap<String, File>();
         for (Map<String, NamedCorePluginFolder> map : plugins.values())
         {
@@ -178,7 +183,6 @@ public class CorePluginsInjector
             }
         }
         return pluginFolders;
-
     }
 
     private void injectProperty(Properties properties, String key, String value)
@@ -199,33 +203,15 @@ public class CorePluginsInjector
     {
         Map<IPluginType, Map<String, NamedCorePluginFolder>> typeToPluginsMap =
                 new LinkedHashMap<IPluginType, Map<String, NamedCorePluginFolder>>();
-        CorePluginScanner scanner =
-                new CorePluginScanner(corePluginsFolderPath, scannerType, logger);
+        CorePluginScanner scanner = new CorePluginScanner(corePluginsFolderPath, scannerType, logger);
         List<CorePlugin> plugins = scanner.scanForPlugins();
 
-        // this loop is here just to log unregistered plugins
-        for (CorePlugin plugin : plugins)
-        {
-            String module = plugin.getName();
-            if (moduleEnabledChecker.isModuleEnabled(module) == false)
-            {
-                logger.log(LogLevel.INFO, "Core plugins for module '" + module
-                        + "' are not enabled.");
-                continue;
-            }
-        }
-
-        for (CorePlugin corePlugin : moduleEnabledChecker.getListOfEnabledPlugins(plugins))
+        Set<String> enabledPlugins = moduleEnabledChecker.getEnabledPlugins(plugins);
+        for (CorePlugin corePlugin : plugins)
         {
             String module = corePlugin.getName();
-            if (moduleEnabledChecker.isModuleEnabled(module) == false)
-            {
-                throw new IllegalStateException(
-                        "Error in core plugin initialization. Core plugin " + module + " is not enabled, but passed early initialization test.");
-            }
-
             // special treatment for initialize master data, as it is not a core plugin atm
-            if (isDisabled(disabledPlugins, module + ":" + INITIALIZE_MASTER_DATA_CORE_PLUGIN_NAME))
+            if (isDisabled(enabledPlugins, disabledPlugins, module + ":" + INITIALIZE_MASTER_DATA_CORE_PLUGIN_NAME))
             {
                 disabledMasterDataInitialization.add(module);
             }
@@ -251,19 +237,17 @@ public class CorePluginsInjector
                         NamedCorePluginFolder plugin =
                                 new NamedCorePluginFolder(module, pluginType, pluginFolder);
                         String fullPluginName = plugin.getFullPluginName();
-                        if (isDisabled(disabledPlugins, fullPluginName) == false)
+                        if (isDisabled(enabledPlugins, disabledPlugins, fullPluginName) == false)
                         {
                             String fullPluginKey =
                                     pluginType.getPrefix()
                                             + pluginType.getPluginKey(module, pluginName,
                                                     plugin.getPluginProperties());
                             assertAndAddPluginName(fullPluginKey, pluginNames, pluginType);
-                            Map<String, NamedCorePluginFolder> map =
-                                    typeToPluginsMap.get(pluginType);
+                            Map<String, NamedCorePluginFolder> map = typeToPluginsMap.get(pluginType);
                             if (map == null)
                             {
-                                map =
-                                        new LinkedHashMap<String, CorePluginsInjector.NamedCorePluginFolder>();
+                                map = new LinkedHashMap<String, CorePluginsInjector.NamedCorePluginFolder>();
                                 typeToPluginsMap.put(pluginType, map);
                             }
                             map.put(fullPluginKey, plugin);
@@ -274,8 +258,8 @@ public class CorePluginsInjector
         }
         return typeToPluginsMap;
     }
-
-    private boolean isDisabled(List<String> disabledPlugins, String fullPluginName)
+    
+    private boolean isDisabled(Set<String> enabledPlugins, List<String> disabledPlugins, String fullPluginName)
     {
         for (String disabledPlugin : disabledPlugins)
         {
@@ -284,7 +268,14 @@ public class CorePluginsInjector
                 return true;
             }
         }
-        return false;
+        for (String enabledPlugin : enabledPlugins)
+        {
+            if (fullPluginName.startsWith(enabledPlugin))
+            {
+                return false;
+            }
+        }
+        return true;
     }
 
     private void assertAndAddPluginName(String pluginName, Set<String> pluginNames,
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/ModuleEnabledChecker.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/ModuleEnabledChecker.java
index 5b7c2d233d40a883bb5db26614c225fbcfb3b6dd..82ddf5c6aeb6a8b273396880c9428c34ab47ec7f 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/ModuleEnabledChecker.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/ModuleEnabledChecker.java
@@ -16,15 +16,22 @@
 
 package ch.systemsx.cisd.openbis.generic.shared.coreplugin;
 
+import static ch.systemsx.cisd.openbis.generic.shared.coreplugin.CorePluginsInjector.INITIALIZE_MASTER_DATA_CORE_PLUGIN_NAME;
+
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Properties;
+import java.util.Set;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
+import ch.systemsx.cisd.common.collection.IKeyExtractor;
+import ch.systemsx.cisd.common.collection.TableMap;
 import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException;
 import ch.systemsx.cisd.common.properties.PropertyUtils;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CorePlugin;
@@ -36,6 +43,15 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.CorePlugin;
  */
 public class ModuleEnabledChecker
 {
+    private static final IKeyExtractor<String, CorePlugin> CORE_PLUGIN_NAME_EXTRACTOR = new IKeyExtractor<String, CorePlugin>()
+        {
+            @Override
+            public String getKey(CorePlugin corePlugin)
+            {
+                return corePlugin.getName();
+            }
+        };
+
     private final List<Pattern> enabledModulesPatterns;
 
     public ModuleEnabledChecker(Properties properties, String key)
@@ -59,12 +75,67 @@ public class ModuleEnabledChecker
         }
     }
 
-    public static interface IModuleNameExtractor<T>
+    public Set<CorePlugin> getModuleWithEnabledMasterDataInitializations(List<CorePlugin> corePlugins)
+    {
+        Set<CorePlugin> result = new LinkedHashSet<>();
+        TableMap<String, CorePlugin> pluginsByName = new TableMap<>(corePlugins, CORE_PLUGIN_NAME_EXTRACTOR);
+        for (String enabledPlugin : getEnabledPlugins(corePlugins))
+        {
+            CorePlugin plugin = getPluginByFullRequiredPluginName(pluginsByName, enabledPlugin, null);
+            String name = plugin.getName();
+            if (enabledPlugin.equals(name) 
+                    || enabledPlugin.equals(name + ":" + INITIALIZE_MASTER_DATA_CORE_PLUGIN_NAME))
+            {
+                result.add(plugin);
+            }
+        }
+        return result;
+    }
+    
+    Set<String> getEnabledPlugins(List<CorePlugin> corePlugins)
+    {
+        TableMap<String, CorePlugin> pluginsByName = new TableMap<>(corePlugins, CORE_PLUGIN_NAME_EXTRACTOR);
+        Set<String> result = new LinkedHashSet<>();
+        for (CorePlugin corePlugin : getListOfEnabledPlugins(corePlugins))
+        {
+            addRequiredPlugins(result, new HashSet<CorePlugin>(), pluginsByName, corePlugin);
+            result.add(corePlugin.getName());
+        }
+        return result;
+    }
+
+    private void addRequiredPlugins(Set<String> result, Set<CorePlugin> visitedPlugins, 
+            TableMap<String, CorePlugin> pluginsByName, CorePlugin corePlugin)
     {
-        String getName(T item);
+        if (visitedPlugins.contains(corePlugin))
+        {
+            return;
+        }
+        visitedPlugins.add(corePlugin);
+        for (String requiredPlugin : corePlugin.getRequiredPlugins())
+        {
+            CorePlugin referredPlugin = getPluginByFullRequiredPluginName(pluginsByName, requiredPlugin, corePlugin);
+            addRequiredPlugins(result, visitedPlugins, pluginsByName, referredPlugin);
+            result.add(requiredPlugin);
+        }
     }
 
-    public List<CorePlugin> getListOfEnabledPlugins(List<CorePlugin> corePlugins)
+    private CorePlugin getPluginByFullRequiredPluginName(TableMap<String, CorePlugin> pluginsByName, 
+            String requiredPlugin, CorePlugin corePlugin)
+    {
+        FullPluginName fullPluginName = new FullPluginName(requiredPlugin);
+        String moduleName = fullPluginName.getModule();
+        CorePlugin referredPlugin = pluginsByName.tryGet(moduleName);
+        if (referredPlugin == null)
+        {
+            throw new ConfigurationFailureException("Required plugin '" + requiredPlugin 
+                    + "' specified by core plugin '" + corePlugin + "' refers to the unknown module '" 
+                    + moduleName + "'." );
+        }
+        return referredPlugin;
+    }
+    
+    List<CorePlugin> getListOfEnabledPlugins(List<CorePlugin> corePlugins)
     {
         ArrayList<CorePlugin> result = new ArrayList<>();
 
@@ -82,7 +153,7 @@ public class ModuleEnabledChecker
         }
         return result;
     }
-
+    
     public List<String> getListOfEnabledModules(List<String> moduleNames)
     {
         List<String> remainingModules = new LinkedList<>(moduleNames);
@@ -114,4 +185,53 @@ public class ModuleEnabledChecker
         }
         return false;
     }
+    
+    private static final class FullPluginName
+    {
+        private final String module;
+        private final String pluginType;
+        private final String name;
+        
+        FullPluginName(String nameAsString)
+        {
+            String[] splittedName = nameAsString.split(":");
+            module = splittedName[0];
+            if (splittedName.length > 1)
+            {
+                pluginType = splittedName[1];
+                if (splittedName.length > 2)
+                {
+                    name = splittedName[2];
+                } else
+                {
+                    name = null;
+                }
+            } else
+            {
+                pluginType = null;
+                name = null;
+            }
+        }
+
+        public String getModule()
+        {
+            return module;
+        }
+
+        @Override
+        public String toString()
+        {
+            StringBuilder builder = new StringBuilder(module);
+            if (pluginType != null)
+            {
+                builder.append(':').append(pluginType);
+                if (name != null)
+                {
+                    builder.append(':').append(name);
+                }
+            }
+            return builder.toString();
+        }
+        
+    }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginScannerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginScannerTest.java
index 3a7d56cf7ee9c4c38db5765a630d99b203c50a2d..f2f5e808a4103083c03b94424549ab2d8e3dde4a 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginScannerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginScannerTest.java
@@ -54,6 +54,7 @@ public class CorePluginScannerTest extends AbstractFileSystemTestCase
         CorePlugin plugin = plugins.get(0);
         assertEquals("plugin-X", plugin.getName());
         assertEquals(15, plugin.getVersion());
+        assertEquals("[plugin-Y:drop-boxes]", plugin.getRequiredPlugins().toString());
         assertEquals("TEST-SCRIPT", getMasterDataScript(plugin, scanner).trim());
 
         plugin = plugins.get(1);
@@ -85,6 +86,7 @@ public class CorePluginScannerTest extends AbstractFileSystemTestCase
         CorePlugin plugin = plugins.get(0);
         assertEquals("plugin-X", plugin.getName());
         assertEquals(17, plugin.getVersion());
+        assertEquals("[]", plugin.getRequiredPlugins().toString());
 
         plugin = plugins.get(1);
         assertEquals("plugin-Y", plugin.getName());
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjectorTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjectorTest.java
index 06b4931267934d3aa98a04e9e978dda039ac5317..da75322e40274ecfca141a379ea05386d4a0166f 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjectorTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/CorePluginsInjectorTest.java
@@ -17,6 +17,8 @@
 package ch.systemsx.cisd.openbis.generic.shared.coreplugin;
 
 import static ch.systemsx.cisd.common.maintenance.MaintenanceTaskUtils.DEFAULT_MAINTENANCE_PLUGINS_PROPERTY_NAME;
+import static ch.systemsx.cisd.openbis.generic.shared.Constants.ENABLED_MODULES_KEY;
+import static ch.systemsx.cisd.openbis.generic.shared.coreplugin.CorePluginScanner.CORE_PLUGIN_PROPERTIES_FILE_NAME;
 import static ch.systemsx.cisd.openbis.generic.shared.coreplugin.CorePluginsInjector.DISABLED_CORE_PLUGINS_KEY;
 import static ch.systemsx.cisd.openbis.generic.shared.coreplugin.CorePluginsInjector.PLUGIN_PROPERTIES_FILE_NAME;
 
@@ -45,7 +47,6 @@ import ch.systemsx.cisd.common.logging.LogLevel;
 import ch.systemsx.cisd.common.properties.ExtendedProperties;
 import ch.systemsx.cisd.common.properties.PropertyParametersUtil;
 import ch.systemsx.cisd.common.properties.PropertyUtils;
-import ch.systemsx.cisd.common.test.RecordingMatcher;
 import ch.systemsx.cisd.openbis.generic.server.coreplugin.JettyWebAppPluginInjector;
 import ch.systemsx.cisd.openbis.generic.shared.Constants;
 import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant;
@@ -123,24 +124,6 @@ public class CorePluginsInjectorTest extends AbstractFileSystemTestCase
         context.assertIsSatisfied();
     }
 
-    @Test
-    public void testNoCorePluginsDefined()
-    {
-        final RecordingMatcher<String> logMatcher = new RecordingMatcher<String>();
-        context.checking(new Expectations()
-            {
-                {
-                    one(logger).log(with(LogLevel.WARN), with(logMatcher));
-                }
-            });
-
-        injector.injectCorePlugins(new Properties());
-
-        assertEquals("Core plugins folder '" + CorePluginsUtils.DEFAULT_CORE_PLUGINS_FOLDER
-                + "' does not exists.", logMatcher.recordedObject());
-        context.assertIsSatisfied();
-    }
-
     @Test
     public void testMissingPluginProperties()
     {
@@ -376,6 +359,46 @@ public class CorePluginsInjectorTest extends AbstractFileSystemTestCase
 
         context.assertIsSatisfied();
     }
+    
+    @Test
+    public void testDependentPlugins()
+    {
+        File r1 = new File(corePluginsFolder, "dep2/2/dss/reporting-plugins/r1");
+        r1.mkdirs();
+        FileUtilities.writeToFile(new File(r1, PLUGIN_PROPERTIES_FILE_NAME), "");
+        File dpa = new File(corePluginsFolder, "dep/1/dss/drop-boxes/a");
+        dpa.mkdirs();
+        FileUtilities.writeToFile(new File(dpa, PLUGIN_PROPERTIES_FILE_NAME), "");
+        File dpb = new File(corePluginsFolder, "dep/1/dss/drop-boxes/b");
+        dpb.mkdirs();
+        FileUtilities.writeToFile(new File(dpb, PLUGIN_PROPERTIES_FILE_NAME), "");
+        File s1 = new File(corePluginsFolder, "dep/1/dss/services/s1");
+        s1.mkdirs();
+        FileUtilities.writeToFile(new File(s1, PLUGIN_PROPERTIES_FILE_NAME), "");
+        File s2 = new File(corePluginsFolder, "dep/1/dss/services/s2");
+        s2.mkdirs();
+        FileUtilities.writeToFile(new File(s2, PLUGIN_PROPERTIES_FILE_NAME), "");
+        FileUtilities.writeToFile(new File(corePluginsFolder, "dep/1/" + CORE_PLUGIN_PROPERTIES_FILE_NAME), 
+                CorePluginScanner.REQUIRED_PLUGINS_KEY + " = dep2:reporting-plugins, dep2:services");
+        File misc = new File(corePluginsFolder, "screening/1/dss/miscellaneous/c");
+        misc.mkdirs();
+        FileUtilities.writeToFile(new File(misc, PLUGIN_PROPERTIES_FILE_NAME), "");
+        FileUtilities.writeToFile(new File(corePluginsFolder, "screening/1/" + CORE_PLUGIN_PROPERTIES_FILE_NAME), 
+                CorePluginScanner.REQUIRED_PLUGINS_KEY + " = dep:drop-boxes:a, dep:services");
+        
+        Properties properties = createProperties();
+        preparePluginNameLog("dep2:reporting-plugins:r1 [" + r1 + "]", "dep:drop-boxes:a [" + dpa + "]", 
+                "dep:services:s1 [" + s1 + "]", 
+                "dep:services:s2 [" + s2 + "]", "screening:miscellaneous:c [" + misc + "]");
+        
+        injector.injectCorePlugins(properties);
+        
+        assertProperties(corePluginsFolderProperty 
+                + Constants.DISABLED_MASTER_DATA_INITIALIZATION + " = dep,dep2\n" + enabledScreeningProperty
+                + "inputs = a\n" + "plugin-services = s1, s2\n"
+                + "reporting-plugins = r1\n", properties);
+        context.assertIsSatisfied();
+    }
 
     @Test
     public void testDisabledPluginsByPropertiesAndNotEnabledTechnology()
@@ -392,20 +415,22 @@ public class CorePluginsInjectorTest extends AbstractFileSystemTestCase
         File dp2 = new File(corePluginsFolder, "screening/1/dss/drop-boxes/dp2");
         dp2.mkdirs();
         FileUtilities.writeToFile(new File(dp2, PLUGIN_PROPERTIES_FILE_NAME), "");
-        new File(corePluginsFolder, "proteomics/1/dss/drop-boxes/dp3").mkdirs();
-        new File(corePluginsFolder, "proteomics/1/dss/reporting-plugins/r1").mkdirs();
+        File dp3 = new File(corePluginsFolder, "proteomics/1/dss/drop-boxes/dp3");
+        dp3.mkdirs();
+        FileUtilities.writeToFile(new File(dp3, PLUGIN_PROPERTIES_FILE_NAME), "");
         Properties properties = createProperties();
         properties.setProperty(DISABLED_CORE_PLUGINS_KEY,
-                "screening:miscellaneous, screening:drop-boxes:dp1, screening:" + CorePluginsInjector.INITIALIZE_MASTER_DATA_CORE_PLUGIN_NAME);
+                "screening:miscellaneous, screening:drop-boxes:dp1, screening:"
+                        + CorePluginsInjector.INITIALIZE_MASTER_DATA_CORE_PLUGIN_NAME);
         preparePluginNameLog("screening:drop-boxes:dp2 [" + dp2 + "]");
-        prepareNotEnabledTechnology("proteomics");
 
         injector.injectCorePlugins(properties);
 
         assertProperties(corePluginsFolderProperty
                 + "disabled-core-plugins = screening:miscellaneous, screening:drop-boxes:dp1, screening:"
                 + CorePluginsInjector.INITIALIZE_MASTER_DATA_CORE_PLUGIN_NAME + "\n"
-                + Constants.DISABLED_MASTER_DATA_INITIALIZATION + " = screening\n" + enabledScreeningProperty + "inputs = dp2\n", properties);
+                + Constants.DISABLED_MASTER_DATA_INITIALIZATION + " = proteomics,screening\n" 
+                + enabledScreeningProperty + "inputs = dp2\n", properties);
         context.assertIsSatisfied();
     }
 
@@ -587,17 +612,6 @@ public class CorePluginsInjectorTest extends AbstractFileSystemTestCase
             });
     }
 
-    private void prepareNotEnabledTechnology(final String module)
-    {
-        context.checking(new Expectations()
-            {
-                {
-                    one(logger).log(LogLevel.INFO,
-                            "Core plugins for module '" + module + "' are not enabled.");
-                }
-            });
-    }
-
     private void assertProperties(String expectedProperties, Properties properties)
     {
         Set<Entry<Object, Object>> entrySet = properties.entrySet();
@@ -623,11 +637,8 @@ public class CorePluginsInjectorTest extends AbstractFileSystemTestCase
     private Properties createProperties(String technologies)
     {
         Properties properties = new ExtendedProperties();
-        properties.setProperty(CorePluginsUtils.CORE_PLUGINS_FOLDER_KEY,
-                corePluginsFolder.getPath());
-        properties
-                .setProperty(ch.systemsx.cisd.openbis.generic.shared.Constants.ENABLED_MODULES_KEY,
-                        technologies);
+        properties.setProperty(CorePluginsUtils.CORE_PLUGINS_FOLDER_KEY, corePluginsFolder.getPath());
+        properties.setProperty(ENABLED_MODULES_KEY, technologies);
         return properties;
     }
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/ModuleEnabledCheckerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/ModuleEnabledCheckerTest.java
index 72300b477ec4073268b4dd8d7b34e17ec3e2a129..a89b0fddad6016e3dd67c124d19b5cee96ef9180 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/ModuleEnabledCheckerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/coreplugin/ModuleEnabledCheckerTest.java
@@ -18,8 +18,10 @@ package ch.systemsx.cisd.openbis.generic.shared.coreplugin;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Properties;
+import java.util.Set;
 
 import org.testng.annotations.Test;
 
@@ -128,7 +130,7 @@ public class ModuleEnabledCheckerTest extends TestCase
         {
             expectedCorePluginsList.add(new CorePlugin(plugin, 1));
         }
-        List<CorePlugin> enabledPlugins = checker.getListOfEnabledPlugins(corePluginsList);
+        Collection<CorePlugin> enabledPlugins = checker.getListOfEnabledPlugins(corePluginsList);
         assertEquals(expectedCorePluginsList.toString(), enabledPlugins.toString());
     }
 
@@ -137,4 +139,62 @@ public class ModuleEnabledCheckerTest extends TestCase
     {
         new ModuleEnabledChecker(Arrays.asList("[a-b)*"));
     }
+    
+    @Test
+    public void testGetEnabledPluginsWithRequiredPluginOfNonExistentModule()
+    {
+        ModuleEnabledChecker checker = listFactory.create("a.*, beta");
+        try
+        {
+            List<CorePlugin> plugins = Arrays.asList(corePlugin("beta", 1, "g:drop-boxes:g2"));
+            checker.getEnabledPlugins(plugins);
+            fail("ConfigurationFailureException expected");
+        } catch (ConfigurationFailureException ex)
+        {
+            assertEquals("Required plugin 'g:drop-boxes:g2' specified by core plugin "
+                    + "'Core Plugin[name='beta', version='1', required plugins:[g:drop-boxes:g2]]' "
+                    + "refers to the unknown module 'g'.", ex.getMessage());
+        }
+    }
+    
+    @Test
+    public void testGetEnabledPluginsRequiredPlugin()
+    {
+        ModuleEnabledChecker checker = listFactory.create("beta, a.*");
+        List<CorePlugin> plugins = Arrays.asList(corePlugin("alpha", 2), 
+                corePlugin("beta", 1, "gamma:drop-boxes"), 
+                corePlugin("gamma", 1, "beta:services:s1", "delta:maintenance-tasks"),
+                corePlugin("delta", 3));
+        
+        Set<String> enabledPlugins = checker.getEnabledPlugins(plugins);
+        
+        assertEquals("[beta:services:s1, delta:maintenance-tasks, gamma:drop-boxes, beta, alpha]", 
+                enabledPlugins.toString());
+    }
+    
+    @Test
+    public void testGetModuleWithEnabledMasterDataInitializations()
+    {
+        ModuleEnabledChecker checker = listFactory.create("beta, a.*");
+        List<CorePlugin> plugins = Arrays.asList(corePlugin("alpha", 2), 
+                corePlugin("beta", 1, "gamma:" + CorePluginsInjector.INITIALIZE_MASTER_DATA_CORE_PLUGIN_NAME),
+                corePlugin("gamma", 7));
+        
+        Set<CorePlugin> corePlugins = checker.getModuleWithEnabledMasterDataInitializations(plugins);
+        
+        assertEquals("[Core Plugin[name='gamma', version='7'], "
+                + "Core Plugin[name='beta', version='1', required plugins:[gamma:initialize-master-data]], "
+                + "Core Plugin[name='alpha', version='2']]", 
+                corePlugins.toString());
+    }
+    
+    private CorePlugin corePlugin(String name, int version, String... requiredPlugins)
+    {
+        CorePlugin corePlugin = new CorePlugin(name, version);
+        for (String requiredPlugin : requiredPlugins)
+        {
+            corePlugin.addRequiredPlugin(requiredPlugin);
+        }
+        return corePlugin;
+    }
 }