diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java
index afdefe5..81cb083 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java
@@ -55,6 +55,7 @@ import com.google.common.io.Closer;
 
 import org.apache.jackrabbit.oak.api.ContentRepository;
 import org.apache.jackrabbit.oak.api.ContentSession;
+import org.apache.jackrabbit.oak.api.Descriptors;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.jmx.QueryEngineSettingsMBean;
 import org.apache.jackrabbit.oak.api.jmx.RepositoryManagementMBean;
@@ -97,9 +98,11 @@ import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.spi.whiteboard.CompositeRegistration;
 import org.apache.jackrabbit.oak.spi.whiteboard.DefaultWhiteboard;
 import org.apache.jackrabbit.oak.spi.whiteboard.Registration;
+import org.apache.jackrabbit.oak.spi.whiteboard.Tracker;
 import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
 import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardAware;
 import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils;
+import org.apache.jackrabbit.oak.util.AggregatingDescriptors;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -611,13 +614,16 @@ public class Oak {
         regs.add(registerMBean(whiteboard, RepositoryManagementMBean.class, repositoryManager,
                 RepositoryManagementMBean.TYPE, repositoryManager.getName()));
 
+        final Tracker<Descriptors> t = whiteboard.track(Descriptors.class);
+
         return new ContentRepositoryImpl(
                 store,
                 CompositeHook.compose(commitHooks),
                 defaultWorkspaceName,
                 queryEngineSettings,
                 indexProvider,
-                securityProvider) {
+                securityProvider,
+                AggregatingDescriptors.aggregate(t.getServices())) {
             @Override
             public void close() throws IOException {
                 super.close();
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java
index ef7a56d..69f9df5 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/core/ContentRepositoryImpl.java
@@ -116,6 +116,7 @@ public class ContentRepositoryImpl implements ContentRepository, Closeable {
     private final SecurityProvider securityProvider;
     private final QueryIndexProvider indexProvider;
     private final QueryEngineSettings queryEngineSettings;
+    private final Descriptors baseDescriptors;
 
     private GenericDescriptors descriptors;
     
@@ -134,13 +135,15 @@ public class ContentRepositoryImpl implements ContentRepository, Closeable {
                                  @Nonnull String defaultWorkspaceName,
                                  QueryEngineSettings queryEngineSettings,
                                  @Nullable QueryIndexProvider indexProvider,
-                                 @Nonnull SecurityProvider securityProvider) {
+                                 @Nonnull SecurityProvider securityProvider,
+                                 @Nullable Descriptors baseDescriptors) {
         this.nodeStore = checkNotNull(nodeStore);
         this.commitHook = checkNotNull(commitHook);
         this.defaultWorkspaceName = checkNotNull(defaultWorkspaceName);
         this.securityProvider = checkNotNull(securityProvider);
         this.queryEngineSettings = queryEngineSettings != null ? queryEngineSettings : new QueryEngineSettings();
         this.indexProvider = indexProvider != null ? indexProvider : new CompositeQueryIndexProvider();
+        this.baseDescriptors = baseDescriptors;
     }
 
     @Nonnull
@@ -185,7 +188,7 @@ public class ContentRepositoryImpl implements ContentRepository, Closeable {
         final Value trueValue = valueFactory.createValue(true);
         final Value falseValue = valueFactory.createValue(false);
 
-        GenericDescriptors gd = new GenericDescriptors()
+        GenericDescriptors gd = new GenericDescriptors(baseDescriptors)
                 .put(IDENTIFIER_STABILITY, valueFactory.createValue(Repository.IDENTIFIER_STABILITY_METHOD_DURATION), true, true)
                 .put(LEVEL_1_SUPPORTED, trueValue, true, true)
                 .put(LEVEL_2_SUPPORTED, trueValue, true, true)
diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/util/AggregatingDescriptors.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/util/AggregatingDescriptors.java
new file mode 100644
index 0000000..1d7af85
--- /dev/null
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/util/AggregatingDescriptors.java
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.util;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import javax.jcr.Value;
+
+import org.apache.jackrabbit.oak.api.Descriptors;
+
+/**
+ * An AggregatingDescriptors is an implementation of Descriptors
+ * that allows to aggregate multiple Descriptors underneath.
+ * <p>
+ * Descriptors can be added via add(Descriptors).
+ * @see #add(Descriptors)
+ */
+public class AggregatingDescriptors implements Descriptors {
+
+    private List<Descriptors> descriptorsList = new LinkedList<Descriptors>();
+
+    /**
+     * Creates a Descriptors which is the aggregate of the passed list of 
+     * Descriptors - or in case the list is only one it returns the one -
+     * or if the list is empty it returns null
+     * @return null if the list is empty, the one Descriptors if the list
+     * contains only one entry or an aggregating Descriptors if the list
+     * contains two or more entries
+     */
+    public static Descriptors aggregate(List<Descriptors> descriptors) {
+        if (descriptors==null || descriptors.size()==0) {
+            return null;
+        }
+        if (descriptors.size()==1) {
+            return descriptors.get(0);
+        } else {
+            AggregatingDescriptors aggregator = new AggregatingDescriptors();
+            for (Iterator<Descriptors> it = descriptors.iterator(); it.hasNext();) {
+                aggregator.add(it.next());
+            }
+            return aggregator;
+        }
+    }
+    
+    /**
+     * Create an empty AggregatingDescriptors.
+     * <p>
+     * Note: add Descriptors via add(Descriptors)
+     * @see #add(Descriptors)
+     */
+    public AggregatingDescriptors() {
+        // empty
+    }
+    
+    /**
+     * Creates an AggregatingDescriptors that already contains
+     * one Descriptors.
+     * <p>
+     * Additional descriptors can be added via add(Descriptors)
+     * @see #add(Descriptors)
+     */
+    public AggregatingDescriptors(Descriptors descriptors) {
+        add(descriptors);
+    }
+    
+    /**
+     * Add a Descriptors to this AggregatingDescriptors.
+     * @param descriptors the Descriptors to add
+     */
+    public void add(Descriptors descriptors) {
+        descriptorsList.add(descriptors);
+    }
+    
+    /**
+     * Return a Descriptors from this AggregatingDescriptors.
+     * @param descriptors the Descriptors to remove
+     * @return true if the Descriptors was added in the first place,
+     * false if it was never part of this AggregatingDescriptors
+     */
+    public boolean remove(Descriptors descriptors) {
+        return descriptorsList.add(descriptors);
+    }
+    
+    @Override
+    public String[] getKeys() {
+        Set<String> keys = new HashSet<String>();
+        for (Iterator<Descriptors> it = descriptorsList.iterator(); it.hasNext();) {
+            Descriptors descriptors = it.next();
+            Collections.addAll(keys, descriptors.getKeys());
+        }
+        return keys.toArray(new String[keys.size()]);
+    }
+
+    @Override
+    public boolean isStandardDescriptor(@Nonnull String key) {
+        for (Iterator<Descriptors> it = descriptorsList.iterator(); it.hasNext();) {
+            Descriptors descriptors = it.next();
+            if (descriptors.isStandardDescriptor(key)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean isSingleValueDescriptor(@Nonnull String key) {
+        for (Iterator<Descriptors> it = descriptorsList.iterator(); it.hasNext();) {
+            Descriptors descriptors = it.next();
+            if (descriptors.isSingleValueDescriptor(key)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @CheckForNull
+    @Override
+    public Value getValue(@Nonnull String key) {
+        for (Iterator<Descriptors> it = descriptorsList.iterator(); it.hasNext();) {
+            Descriptors descriptors = it.next();
+            Value value = descriptors.getValue(key);
+            if (value!=null) {
+                return value;
+            }
+        }
+        return null;
+    }
+
+    @CheckForNull
+    @Override
+    public Value[] getValues(@Nonnull String key) {
+        for (Iterator<Descriptors> it = descriptorsList.iterator(); it.hasNext();) {
+            Descriptors descriptors = it.next();
+            Value[] values = descriptors.getValues(key);
+            if (values!=null) {
+                return values;
+            }
+        }
+        return null;
+    }
+
+}
