diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
index 433c4ce4ca8f3a4d6260e2bc64471901d0f41036..1698ab9ce628ffd5d53eb604fed636b370f4f368 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
@@ -90,6 +90,9 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignments;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsCount;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAuthorizationGroup;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewColumnOrFilter;
@@ -159,6 +162,18 @@ public interface ICommonClientService extends IClientService
     public TypedTableResultSet<Metaproject> listMetaprojects(ListMetaprojectsCriteria criteria)
             throws UserFailureException;
 
+    /**
+     * Returns a list of all metaproject assignment counts.
+     */
+    public List<MetaprojectAssignmentsCount> listMetaprojectAssignmentsCounts()
+            throws UserFailureException;
+
+    /**
+     * Returns metaproject assignments.
+     */
+    public MetaprojectAssignments getMetaprojectAssignments(Long metaprojectId,
+            MetaprojectAssignmentsFetchOption[] fetchOptions) throws UserFailureException;
+
     /**
      * Like {@link #prepareExportSamples(TableExportCriteria)}, but for scripts.
      */
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
index 7bda8c8720645c7b4155218a5da415ab4dd3ab58..644fe4c24ccac6fcfc4cdca84370072191566bf5 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
@@ -92,6 +92,9 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignments;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsCount;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAuthorizationGroup;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewColumnOrFilter;
@@ -143,6 +146,18 @@ public interface ICommonClientServiceAsync extends IClientServiceAsync
     public void listMetaprojects(ListMetaprojectsCriteria criteria,
             final AsyncCallback<TypedTableResultSet<Metaproject>> asyncCallback);
 
+    /** @see ICommonClientService#listMetaprojectAssignmentsCounts() */
+    public void listMetaprojectAssignmentsCounts(
+            final AsyncCallback<List<MetaprojectAssignmentsCount>> asyncCallback);
+
+    /**
+     * @see ICommonClientService#getMetaprojectAssignments(Long,
+     *      MetaprojectAssignmentsFetchOption[])
+     */
+    public void getMetaprojectAssignments(Long metaprojectId,
+            MetaprojectAssignmentsFetchOption[] fetchOptions,
+            final AsyncCallback<MetaprojectAssignments> asyncCallback);
+
     /** @see ICommonClientService#prepareExportScripts(TableExportCriteria) */
     public void prepareExportScripts(
             TableExportCriteria<TableModelRowWithObject<Script>> exportCriteria,
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
index de33dd5e361ed7d6df573f3cd30eabfc1ea7464f..879ad557054744aa0b265d80bd19e2404f51bbbe 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
@@ -950,6 +950,24 @@ public abstract class Dict
     //
     public static final String PROJECT_REGISTRATION = "project_registration";
 
+    //
+    // Metaproject Tree
+    //
+
+    public static final String METAPROJECT_TREE_COLUMN_HEADER = "metaproject_tree_column_header";
+
+    public static final String METAPROJECT_TREE_INFO_LINK = "metaproject_tree_info_link";
+
+    //
+    // Metaproject Browser
+    //
+    public static final String METAPROJECT_BROWSER = "metaproject_browser";
+
+    public static final String METAPROJECT_BROWSER_TREE_TITLE = "metaproject_browser_tree_title";
+
+    public static final String METAPROJECT_BROWSER_TREE_TOOLTIP =
+            "metaproject_browser_tree_tooltip";
+
     //
     // Detailed Search
     //
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java
index bd888a95d8ff344328a525372de8bb010391465c..e237ea8f17fa8e9b4650572bfac5ae1cb60d496c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/ComponentProvider.java
@@ -48,6 +48,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.ID
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.material.MaterialBatchRegistrationUpdatePanel;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.material.MaterialBrowserGrid;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.material.MaterialTypeGrid;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.browser.MetaprojectBrowser;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.project.ProjectGrid;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.project.ProjectRegistrationForm;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.property_type.PropertyTypeAssignmentForm;
@@ -975,6 +976,44 @@ public final class ComponentProvider
             };
     }
 
+    public final AbstractTabItemFactory getMetaprojectBrowser()
+    {
+        return new AbstractTabItemFactory()
+            {
+                @Override
+                public ITabItem create()
+                {
+                    IDisposableComponent browser = new MetaprojectBrowser(viewContext);
+                    return createTab(getTabTitle(), browser);
+                }
+
+                @Override
+                public String getId()
+                {
+                    return MetaprojectBrowser.ID;
+                }
+
+                @Override
+                public HelpPageIdentifier getHelpPageIdentifier()
+                {
+                    return new HelpPageIdentifier(HelpPageDomain.METAPROJECT, HelpPageAction.BROWSE);
+                }
+
+                @Override
+                public String getTabTitle()
+                {
+                    return getMessage(Dict.METAPROJECT_BROWSER);
+                }
+
+                @Override
+                public String tryGetLink()
+                {
+                    return null;
+                }
+
+            };
+    }
+
     public final AbstractTabItemFactory getDeletionBrowser()
     {
         return new AbstractTabItemFactory()
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/help/HelpPageIdentifier.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/help/HelpPageIdentifier.java
index a899e5375809dbfff396f824e27dc526fd278c92..9795ffb0c46e7ec858d3c740308438cdb2a36201 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/help/HelpPageIdentifier.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/help/HelpPageIdentifier.java
@@ -51,6 +51,8 @@ public class HelpPageIdentifier
 
         PROJECT(ADMINISTRATION),
 
+        METAPROJECT(ADMINISTRATION),
+
         VOCABULARY(ADMINISTRATION),
         // vocabulary subdomains
         TERM(VOCABULARY),
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/TopMenu.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/TopMenu.java
index 2e6566fc92a2fc92740aedcb3dcfbd21e8afe828..4959fac65f1feeb8d798a362f0ccd8a376f6d9e1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/TopMenu.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/TopMenu.java
@@ -50,10 +50,8 @@ public class TopMenu extends LayoutContainer
     /** {@link ActionMenu} kind enum with names matching dictionary keys */
     public static enum ActionMenuKind implements IActionMenuItem
     {
-        ADMINISTRATION_MENU_MANAGE_GROUPS,
-        ADMINISTRATION_MENU_MANAGE_TYPES,
-        ADMINISTRATION_MENU_MANAGE_PROPERTY_TYPES,
-        ADMINISTRATION_MENU_MANAGE_AUTHORIZATION,
+        ADMINISTRATION_MENU_MANAGE_GROUPS, ADMINISTRATION_MENU_MANAGE_TYPES,
+        ADMINISTRATION_MENU_MANAGE_PROPERTY_TYPES, ADMINISTRATION_MENU_MANAGE_AUTHORIZATION,
 
         AUTHORIZATION_MENU_USERS, AUTHORIZATION_MENU_ROLES,
         AUTHORIZATION_MENU_AUTHORIZATION_GROUPS,
@@ -75,6 +73,8 @@ public class TopMenu extends LayoutContainer
 
         PROJECT_MENU_BROWSE, PROJECT_MENU_NEW,
 
+        METAPROJECT_MENU_BROWSE,
+
         PROPERTY_TYPES_MENU_BROWSE_PROPERTY_TYPES, PROPERTY_TYPES_MENU_BROWSE_ASSIGNMENTS,
         PROPERTY_TYPES_MENU_NEW_PROPERTY_TYPES, PROPERTY_TYPES_MENU_ASSIGN_TO_EXPERIMENT_TYPE,
         PROPERTY_TYPES_MENU_ASSIGN_TO_MATERIAL_TYPE, PROPERTY_TYPES_MENU_ASSIGN_TO_DATA_SET_TYPE,
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/top/BrowseMenu.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/top/BrowseMenu.java
index 0a1ba6c5558d1be348218f13843bb34274f32c43..bfc6a31c5a6486fdabf9328ee993423a5e869781 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/top/BrowseMenu.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/menu/top/BrowseMenu.java
@@ -50,6 +50,9 @@ public class BrowseMenu extends TopMenuItem
                 componentProvider.getDataSetSearch()));
         submenu.add(new ActionMenu(TopMenu.ActionMenuKind.MATERIAL_MENU_BROWSE, messageProvider,
                 componentProvider.getMaterialBrowser()));
+        submenu.add(new ActionMenu(TopMenu.ActionMenuKind.METAPROJECT_MENU_BROWSE, messageProvider,
+                componentProvider.getMetaprojectBrowser()));
+
         setMenu(submenu);
     }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/MetaprojectBrowserGrids.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/MetaprojectBrowserGrids.java
new file mode 100644
index 0000000000000000000000000000000000000000..8add1dce6be48671df933ea93558091298c1becb
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/experiment/MetaprojectBrowserGrids.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment;
+
+import java.util.Set;
+
+import com.extjs.gxt.ui.client.widget.Composite;
+import com.extjs.gxt.ui.client.widget.Text;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IDisposableComponent;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind;
+
+/**
+ * @author pkupczyk
+ */
+public class MetaprojectBrowserGrids extends Composite implements IDisposableComponent
+{
+
+    public MetaprojectBrowserGrids(IViewContext<?> viewContext)
+    {
+        initComponent(new Text("grids"));
+    }
+
+    @Override
+    public void update(Set<DatabaseModificationKind> observedModifications)
+    {
+    }
+
+    @Override
+    public DatabaseModificationKind[] getRelevantModifications()
+    {
+        return null;
+    }
+
+    @Override
+    public void dispose()
+    {
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/MetaprojectChooserButton.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/MetaprojectChooserButton.java
index 47d6afa993dadfcfd5c275553992a76aa5b105b6..38feba55f10da39ef80c2c2418e1eeb0c68065ea 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/MetaprojectChooserButton.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/MetaprojectChooserButton.java
@@ -28,7 +28,7 @@ import com.extjs.gxt.ui.client.widget.form.Field;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.DisposableEntityChooser;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.MetaprojectGrid;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.grid.MetaprojectGrid;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/DisposableComposite.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/DisposableComposite.java
new file mode 100644
index 0000000000000000000000000000000000000000..d0f924e3e804b953ec4096e9d508d8c1c7421120
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/DisposableComposite.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import com.extjs.gxt.ui.client.widget.Component;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.SetUtils;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind;
+
+/**
+ * @author pkupczyk
+ */
+public class DisposableComposite implements IDisposableComponent
+{
+
+    private Component mainComponent;
+
+    private IDisposableComponent[] subComponents;
+
+    public DisposableComposite(Component mainComponent, IDisposableComponent... subComponents)
+    {
+        this.mainComponent = mainComponent;
+
+        if (subComponents == null)
+        {
+            this.subComponents = new IDisposableComponent[0];
+        } else
+        {
+            this.subComponents = subComponents;
+        }
+
+    }
+
+    @Override
+    public Component getComponent()
+    {
+        return mainComponent;
+    }
+
+    @Override
+    public void dispose()
+    {
+        for (IDisposableComponent subComponent : subComponents)
+        {
+            subComponent.dispose();
+        }
+    }
+
+    @Override
+    public DatabaseModificationKind[] getRelevantModifications()
+    {
+        Set<DatabaseModificationKind> relevantModifications =
+                new HashSet<DatabaseModificationKind>();
+
+        for (IDisposableComponent subComponent : subComponents)
+        {
+            SetUtils.addAll(relevantModifications, subComponent.getRelevantModifications());
+        }
+
+        return relevantModifications.toArray(DatabaseModificationKind.EMPTY_ARRAY);
+    }
+
+    @Override
+    public void update(Set<DatabaseModificationKind> observedModifications)
+    {
+        for (IDatabaseModificationObserver subComponent : subComponents)
+        {
+            if (SetUtils
+                    .containsAny(observedModifications, subComponent.getRelevantModifications()))
+            {
+                subComponent.update(observedModifications);
+            }
+        }
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/browser/MetaprojectBrowser.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/browser/MetaprojectBrowser.java
new file mode 100644
index 0000000000000000000000000000000000000000..bec3717cb1ebd65f2fce230026ae1c342b50b49c
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/browser/MetaprojectBrowser.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.browser;
+
+import java.util.Set;
+
+import com.extjs.gxt.ui.client.Style.LayoutRegion;
+import com.extjs.gxt.ui.client.util.Margins;
+import com.extjs.gxt.ui.client.widget.Component;
+import com.extjs.gxt.ui.client.widget.ContentPanel;
+import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
+import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.experiment.MetaprojectBrowserGrids;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.DisposableComposite;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IDisposableComponent;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind;
+
+/**
+ * @author pkupczyk
+ */
+public class MetaprojectBrowser extends ContentPanel implements IDisposableComponent
+{
+
+    public static final String ID = GenericConstants.ID_PREFIX + "metaproject-browser";
+
+    private MetaprojectBrowserTree tree;
+
+    private MetaprojectBrowserGrids grids;
+
+    private DisposableComposite composite;
+
+    public MetaprojectBrowser(final IViewContext<?> viewContext)
+    {
+        setId(ID);
+        setLayout(new BorderLayout());
+
+        tree = new MetaprojectBrowserTree(viewContext);
+        // GWTUtils.setToolTip(tree, viewContext.getMessage(Dict.METAPROJECT_BROWSER_TREE_TOOLTIP));
+
+        grids = new MetaprojectBrowserGrids(viewContext);
+        composite = new DisposableComposite(this, tree, grids);
+
+        BorderLayoutData treeLayout = new BorderLayoutData(LayoutRegion.WEST, 200, 20, 2000);
+        treeLayout.setSplit(true);
+        treeLayout.setMargins(new Margins(2));
+        treeLayout.setCollapsible(true);
+        treeLayout.setFloatable(false);
+
+        BorderLayoutData gridsLayout = new BorderLayoutData(LayoutRegion.CENTER, 200, 20, 2000);
+        gridsLayout.setSplit(true);
+        gridsLayout.setMargins(new Margins(2));
+        gridsLayout.setCollapsible(true);
+        gridsLayout.setFloatable(false);
+
+        add(tree, treeLayout);
+        add(grids, gridsLayout);
+
+        layout();
+    }
+
+    @Override
+    public Component getComponent()
+    {
+        return composite.getComponent();
+    }
+
+    @Override
+    public void dispose()
+    {
+        composite.dispose();
+    }
+
+    @Override
+    public DatabaseModificationKind[] getRelevantModifications()
+    {
+        return composite.getRelevantModifications();
+    }
+
+    @Override
+    public void update(Set<DatabaseModificationKind> observedModifications)
+    {
+        composite.update(observedModifications);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/browser/MetaprojectBrowserTree.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/browser/MetaprojectBrowserTree.java
new file mode 100644
index 0000000000000000000000000000000000000000..62e53c36bae903b2a8b2843db5e64d2e2cdd3207
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/browser/MetaprojectBrowserTree.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.browser;
+
+import java.util.Set;
+
+import com.extjs.gxt.ui.client.widget.Component;
+import com.extjs.gxt.ui.client.widget.ContentPanel;
+import com.extjs.gxt.ui.client.widget.layout.FitLayout;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IDisposableComponent;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.MetaprojectTree;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind;
+
+/**
+ * @author pkupczyk
+ */
+public final class MetaprojectBrowserTree extends ContentPanel implements IDisposableComponent
+{
+
+    public static final String ID = GenericConstants.ID_PREFIX + "metaproject-browser-tree-panel";
+
+    private final MetaprojectTree tree;
+
+    public MetaprojectBrowserTree(final IViewContext<?> viewContext)
+    {
+        setLayout(new FitLayout());
+        setBodyBorder(false);
+        setHeading(viewContext.getMessage(Dict.METAPROJECT_BROWSER_TREE_TITLE));
+
+        tree = new MetaprojectTree(viewContext);
+        add(tree);
+    }
+
+    @Override
+    public void update(Set<DatabaseModificationKind> observedModifications)
+    {
+
+    }
+
+    @Override
+    public DatabaseModificationKind[] getRelevantModifications()
+    {
+        return null;
+    }
+
+    @Override
+    public Component getComponent()
+    {
+        return null;
+    }
+
+    @Override
+    public void dispose()
+    {
+
+    }
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/MetaprojectGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/grid/MetaprojectGrid.java
similarity index 99%
rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/MetaprojectGrid.java
rename to openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/grid/MetaprojectGrid.java
index b217957202ad145aae666f1070797eedce561c7b..163813e2a673042a352cefc16a38b7960e42f8c8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/MetaprojectGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/grid/MetaprojectGrid.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject;
+package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.grid;
 
 import java.util.Arrays;
 import java.util.HashSet;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/MetaprojectTree.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/MetaprojectTree.java
new file mode 100644
index 0000000000000000000000000000000000000000..342cc90fcd41870d3ecab5ec872548545916dd0d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/MetaprojectTree.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.extjs.gxt.ui.client.Style.SelectionMode;
+import com.extjs.gxt.ui.client.data.BaseTreeLoader;
+import com.extjs.gxt.ui.client.data.RpcProxy;
+import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
+import com.extjs.gxt.ui.client.event.SelectionChangedListener;
+import com.extjs.gxt.ui.client.store.ListStore;
+import com.extjs.gxt.ui.client.store.TreeStore;
+import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
+import com.extjs.gxt.ui.client.widget.grid.ColumnData;
+import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
+import com.extjs.gxt.ui.client.widget.grid.Grid;
+import com.extjs.gxt.ui.client.widget.treegrid.TreeGrid;
+import com.extjs.gxt.ui.client.widget.treegrid.WidgetTreeGridCellRenderer;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Widget;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.model.MetaprojectTreeEntityItemData;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.model.MetaprojectTreeEntityKindItemData;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.model.MetaprojectTreeItemData;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.model.MetaprojectTreeMetaprojectItemData;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.widget.MetaprojectTreeEntityItemWidget;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.widget.MetaprojectTreeEntityKindItemWidget;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.widget.MetaprojectTreeItemWidget;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.widget.MetaprojectTreeMetaprojectItemWidget;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IDelegatedAction;
+import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWithIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignments;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsCount;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsFetchOption;
+
+/**
+ * @author pkupczyk
+ */
+public class MetaprojectTree extends TreeGrid<MetaprojectTreeItemData>
+{
+
+    public static final String ID = GenericConstants.ID_PREFIX + "metaproject-tree";
+
+    public static final String COLUMN_ID = "metaproject-tree-column";
+
+    private MetaprojectTreeItemData selectedItem;
+
+    public MetaprojectTree(IViewContext<?> viewContext)
+    {
+        this(viewContext, new MetaprojectTreeLoader(viewContext), new MetaprojectTreeColumns(
+                viewContext));
+    }
+
+    private MetaprojectTree(final IViewContext<?> viewContext, final MetaprojectTreeLoader loader,
+            final MetaprojectTreeColumns columns)
+    {
+        super(new TreeStore<MetaprojectTreeItemData>(loader), columns.getModel());
+
+        setId(ID);
+        setLazyRowRender(0);
+        setBorders(true);
+        setAutoExpandColumn(COLUMN_ID);
+
+        getTreeView().setForceFit(true);
+        getTreeView().setSortingEnabled(false);
+        getTreeView().setBufferEnabled(false);
+
+        getStyle().setNodeCloseIcon(null);
+        getStyle().setNodeOpenIcon(null);
+
+        getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
+        getSelectionModel().addSelectionChangedListener(
+                new SelectionChangedListener<MetaprojectTreeItemData>()
+                    {
+                        @Override
+                        public void selectionChanged(
+                                SelectionChangedEvent<MetaprojectTreeItemData> se)
+                        {
+                            if (selectedItem != null)
+                            {
+                                MetaprojectTreeItemWidget selectedWidget =
+                                        columns.getWidget(selectedItem);
+                                selectedWidget.setSelected(false);
+                            }
+
+                            selectedItem = se.getSelectedItem();
+
+                            if (selectedItem != null)
+                            {
+                                MetaprojectTreeItemWidget selectedWidget =
+                                        columns.getWidget(selectedItem);
+                                selectedWidget.setSelected(true);
+                            }
+                        }
+                    });
+
+        loader.load();
+    }
+
+    private static class MetaprojectTreeProxy extends RpcProxy<List<MetaprojectTreeItemData>>
+    {
+
+        private IViewContext<?> viewContext;
+
+        private Map<Long, MetaprojectAssignmentsCount> countMap;
+
+        public MetaprojectTreeProxy(IViewContext<?> viewContext)
+        {
+            this.viewContext = viewContext;
+        }
+
+        @Override
+        protected void load(Object parentObject,
+                AsyncCallback<List<MetaprojectTreeItemData>> callback)
+        {
+            if (parentObject == null)
+            {
+                loadMetaprojects(callback);
+            } else if (parentObject instanceof MetaprojectTreeMetaprojectItemData)
+            {
+                loadEntityKinds((MetaprojectTreeMetaprojectItemData) parentObject, callback);
+            } else if (parentObject instanceof MetaprojectTreeEntityKindItemData)
+            {
+                loadEntities((MetaprojectTreeEntityKindItemData) parentObject, callback);
+            } else
+            {
+                throw new IllegalArgumentException("Unsupported parent node: " + parentObject);
+            }
+        }
+
+        private void initCountMap(final IDelegatedAction callback)
+        {
+            viewContext.getCommonService().listMetaprojectAssignmentsCounts(
+                    new AbstractAsyncCallback<List<MetaprojectAssignmentsCount>>(viewContext)
+                        {
+                            @Override
+                            protected void process(List<MetaprojectAssignmentsCount> result)
+                            {
+                                Map<Long, MetaprojectAssignmentsCount> map =
+                                        new HashMap<Long, MetaprojectAssignmentsCount>();
+
+                                for (MetaprojectAssignmentsCount resultItem : result)
+                                {
+                                    map.put(resultItem.getMetaproject().getId(), resultItem);
+                                }
+
+                                MetaprojectTreeProxy.this.countMap = map;
+                                callback.execute();
+                            }
+                        });
+        }
+
+        private void loadMetaprojects(final AsyncCallback<List<MetaprojectTreeItemData>> callback)
+        {
+            if (countMap == null)
+            {
+                initCountMap(new IDelegatedAction()
+                    {
+
+                        @Override
+                        public void execute()
+                        {
+                            loadMetaprojects(callback);
+                        }
+                    });
+            } else
+            {
+                List<MetaprojectTreeItemData> items = new ArrayList<MetaprojectTreeItemData>();
+
+                for (MetaprojectAssignmentsCount count : countMap.values())
+                {
+                    items.add(new MetaprojectTreeMetaprojectItemData(count.getMetaproject()));
+                }
+
+                callback.onSuccess(items);
+            }
+        }
+
+        private void loadEntityKinds(final MetaprojectTreeMetaprojectItemData parent,
+                final AsyncCallback<List<MetaprojectTreeItemData>> callback)
+        {
+            if (countMap == null)
+            {
+                initCountMap(new IDelegatedAction()
+                    {
+
+                        @Override
+                        public void execute()
+                        {
+                            loadEntityKinds(parent, callback);
+                        }
+                    });
+            } else
+            {
+                Long metaprojectId = parent.getMetaproject().getId();
+                MetaprojectAssignmentsCount count = countMap.get(metaprojectId);
+                List<MetaprojectTreeItemData> items = new ArrayList<MetaprojectTreeItemData>();
+
+                if (count.getExperimentCount() > 0)
+                {
+                    items.add(new MetaprojectTreeEntityKindItemData(metaprojectId,
+                            EntityKind.EXPERIMENT, count.getExperimentCount()));
+                }
+                if (count.getSampleCount() > 0)
+                {
+                    items.add(new MetaprojectTreeEntityKindItemData(metaprojectId,
+                            EntityKind.SAMPLE, count.getSampleCount()));
+                }
+                if (count.getDataSetCount() > 0)
+                {
+                    items.add(new MetaprojectTreeEntityKindItemData(metaprojectId,
+                            EntityKind.DATA_SET, count.getDataSetCount()));
+                }
+                if (count.getMaterialCount() > 0)
+                {
+                    items.add(new MetaprojectTreeEntityKindItemData(metaprojectId,
+                            EntityKind.MATERIAL, count.getMaterialCount()));
+                }
+
+                callback.onSuccess(items);
+            }
+        }
+
+        private void loadEntities(final MetaprojectTreeEntityKindItemData parent,
+                final AsyncCallback<List<MetaprojectTreeItemData>> callback)
+        {
+            MetaprojectAssignmentsFetchOption fetchOption =
+                    getAssignmentsFetchOption(parent.getEntityKind());
+
+            viewContext.getCommonService().getMetaprojectAssignments(parent.getMetaprojectId(),
+                    new MetaprojectAssignmentsFetchOption[]
+                        { fetchOption },
+                    new AbstractAsyncCallback<MetaprojectAssignments>(viewContext)
+                        {
+                            @Override
+                            protected void process(MetaprojectAssignments result)
+                            {
+                                List<MetaprojectTreeItemData> items =
+                                        new ArrayList<MetaprojectTreeItemData>();
+                                List<? extends IEntityInformationHolderWithIdentifier> entities =
+                                        getAssignmentsEntities(result, parent.getEntityKind());
+
+                                for (IEntityInformationHolderWithIdentifier entity : entities)
+                                {
+                                    items.add(new MetaprojectTreeEntityItemData(parent
+                                            .getMetaprojectId(), entity));
+                                }
+
+                                callback.onSuccess(items);
+                            }
+                        });
+        }
+    }
+
+    private static class MetaprojectTreeLoader extends BaseTreeLoader<MetaprojectTreeItemData>
+    {
+
+        public MetaprojectTreeLoader(final IViewContext<?> viewContext)
+        {
+            super(new MetaprojectTreeProxy(viewContext));
+        }
+
+        @Override
+        public boolean hasChildren(MetaprojectTreeItemData parent)
+        {
+            return parent == null || parent instanceof MetaprojectTreeMetaprojectItemData
+                    || parent instanceof MetaprojectTreeEntityKindItemData;
+        }
+    }
+
+    private static class MetaprojectTreeColumns
+    {
+
+        private ColumnModel columnModel;
+
+        private Map<MetaprojectTreeItemData, MetaprojectTreeItemWidget> widgetMap =
+                new HashMap<MetaprojectTreeItemData, MetaprojectTreeItemWidget>();
+
+        public MetaprojectTreeColumns(final IViewContext<?> viewContext)
+        {
+            ColumnConfig column =
+                    new ColumnConfig(COLUMN_ID,
+                            viewContext.getMessage(Dict.METAPROJECT_TREE_COLUMN_HEADER), 1);
+            column.setMenuDisabled(true);
+            column.setSortable(false);
+            column.setRenderer(new WidgetTreeGridCellRenderer<MetaprojectTreeItemData>()
+                {
+                    @Override
+                    public Widget getWidget(MetaprojectTreeItemData data, String property,
+                            ColumnData config, int rowIndex, int colIndex,
+                            ListStore<MetaprojectTreeItemData> store,
+                            Grid<MetaprojectTreeItemData> grid)
+                    {
+
+                        MetaprojectTreeItemWidget widget;
+
+                        if (data instanceof MetaprojectTreeMetaprojectItemData)
+                        {
+                            widget =
+                                    new MetaprojectTreeMetaprojectItemWidget(viewContext,
+                                            (MetaprojectTreeMetaprojectItemData) data);
+                        } else if (data instanceof MetaprojectTreeEntityKindItemData)
+                        {
+                            widget =
+                                    new MetaprojectTreeEntityKindItemWidget(viewContext,
+                                            (MetaprojectTreeEntityKindItemData) data);
+                        } else if (data instanceof MetaprojectTreeEntityItemData)
+                        {
+                            widget =
+                                    new MetaprojectTreeEntityItemWidget(viewContext,
+                                            (MetaprojectTreeEntityItemData) data);
+                        } else
+                        {
+                            throw new UnsupportedOperationException(
+                                    "Unsupported metaproject tree item");
+                        }
+
+                        widgetMap.put(data, widget);
+                        return widget;
+                    }
+                });
+
+            columnModel = new ColumnModel(Arrays.asList(column));
+        }
+
+        public ColumnModel getModel()
+        {
+            return columnModel;
+        }
+
+        public MetaprojectTreeItemWidget getWidget(MetaprojectTreeItemData data)
+        {
+            return widgetMap.get(data);
+        }
+
+    }
+
+    private static MetaprojectAssignmentsFetchOption getAssignmentsFetchOption(EntityKind entityKind)
+    {
+        if (EntityKind.EXPERIMENT.equals(entityKind))
+        {
+            return MetaprojectAssignmentsFetchOption.EXPERIMENTS;
+        } else if (EntityKind.SAMPLE.equals(entityKind))
+        {
+            return MetaprojectAssignmentsFetchOption.SAMPLES;
+        } else if (EntityKind.DATA_SET.equals(entityKind))
+        {
+            return MetaprojectAssignmentsFetchOption.DATA_SETS;
+        } else if (EntityKind.MATERIAL.equals(entityKind))
+        {
+            return MetaprojectAssignmentsFetchOption.MATERIALS;
+        } else
+        {
+            throw new IllegalArgumentException("Unsupported entity kind: " + entityKind);
+        }
+    }
+
+    private static List<? extends IEntityInformationHolderWithIdentifier> getAssignmentsEntities(
+            MetaprojectAssignments assignments, EntityKind entityKind)
+    {
+        if (EntityKind.EXPERIMENT.equals(entityKind))
+        {
+            return assignments.getExperiments();
+        } else if (EntityKind.SAMPLE.equals(entityKind))
+        {
+            return assignments.getSamples();
+        } else if (EntityKind.DATA_SET.equals(entityKind))
+        {
+            return assignments.getDataSets();
+        } else if (EntityKind.MATERIAL.equals(entityKind))
+        {
+            return assignments.getMaterials();
+        } else
+        {
+            throw new IllegalArgumentException("Unsupported entity kind: " + entityKind);
+        }
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/model/MetaprojectTreeEntityItemData.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/model/MetaprojectTreeEntityItemData.java
new file mode 100644
index 0000000000000000000000000000000000000000..13bc2aaf56c45b3dc4924564a629a2bdba5641f6
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/model/MetaprojectTreeEntityItemData.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.model;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWithIdentifier;
+
+/**
+ * @author pkupczyk
+ */
+public class MetaprojectTreeEntityItemData extends MetaprojectTreeItemData
+{
+    private static final long serialVersionUID = 1L;
+
+    private Long metaprojectId;
+
+    private IEntityInformationHolderWithIdentifier entity;
+
+    // GWT
+    @SuppressWarnings("unused")
+    private MetaprojectTreeEntityItemData()
+    {
+    }
+
+    public MetaprojectTreeEntityItemData(Long metaprojectId,
+            IEntityInformationHolderWithIdentifier entity)
+    {
+        this.metaprojectId = metaprojectId;
+        this.entity = entity;
+    }
+
+    public Long getMetaprojectId()
+    {
+        return metaprojectId;
+    }
+
+    public IEntityInformationHolderWithIdentifier getEntity()
+    {
+        return entity;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return getMetaprojectId().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        MetaprojectTreeEntityItemData other = (MetaprojectTreeEntityItemData) obj;
+        return getMetaprojectId().equals(other.getMetaprojectId())
+                && getEntity().getEntityKind().equals(other.getEntity().getEntityKind())
+                && getEntity().getId().equals(other.getEntity().getId());
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/model/MetaprojectTreeEntityKindItemData.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/model/MetaprojectTreeEntityKindItemData.java
new file mode 100644
index 0000000000000000000000000000000000000000..721649aaa560324b33e727607b6d0e9dc58cea94
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/model/MetaprojectTreeEntityKindItemData.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.model;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
+
+/**
+ * @author pkupczyk
+ */
+public class MetaprojectTreeEntityKindItemData extends MetaprojectTreeItemData
+{
+    private static final long serialVersionUID = 1L;
+
+    private Long metaprojectId;
+
+    private EntityKind entityKind;
+
+    private int entityCount;
+
+    // GWT
+    @SuppressWarnings("unused")
+    private MetaprojectTreeEntityKindItemData()
+    {
+    }
+
+    public MetaprojectTreeEntityKindItemData(Long metaprojectId, EntityKind entityKind,
+            int entityCount)
+    {
+        this.metaprojectId = metaprojectId;
+        this.entityKind = entityKind;
+        this.entityCount = entityCount;
+    }
+
+    public Long getMetaprojectId()
+    {
+        return metaprojectId;
+    }
+
+    public EntityKind getEntityKind()
+    {
+        return entityKind;
+    }
+
+    public int getEntityCount()
+    {
+        return entityCount;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return getMetaprojectId().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        MetaprojectTreeEntityKindItemData other = (MetaprojectTreeEntityKindItemData) obj;
+        return getMetaprojectId().equals(other.getMetaprojectId())
+                && getEntityKind().equals(other.getEntityKind());
+    }
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/model/MetaprojectTreeItemData.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/model/MetaprojectTreeItemData.java
new file mode 100644
index 0000000000000000000000000000000000000000..436afe1a55c014d831cfebcc8f09c068bed9009b
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/model/MetaprojectTreeItemData.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.model;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.SimplifiedBaseModelData;
+
+/**
+ * @author pkupczyk
+ */
+public class MetaprojectTreeItemData extends SimplifiedBaseModelData
+{
+
+    private static final long serialVersionUID = 1L;
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/model/MetaprojectTreeMetaprojectItemData.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/model/MetaprojectTreeMetaprojectItemData.java
new file mode 100644
index 0000000000000000000000000000000000000000..33ba933b948c8a5873dfc7ca1dcc144872e7c26d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/model/MetaprojectTreeMetaprojectItemData.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.model;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
+
+/**
+ * @author pkupczyk
+ */
+public class MetaprojectTreeMetaprojectItemData extends MetaprojectTreeItemData
+{
+    private static final long serialVersionUID = 1L;
+
+    private Metaproject metaproject;
+
+    // GWT
+    @SuppressWarnings("unused")
+    private MetaprojectTreeMetaprojectItemData()
+    {
+    }
+
+    public MetaprojectTreeMetaprojectItemData(Metaproject metaproject)
+    {
+        this.metaproject = metaproject;
+    }
+
+    public Metaproject getMetaproject()
+    {
+        return metaproject;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return getMetaproject().getId().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        MetaprojectTreeMetaprojectItemData other = (MetaprojectTreeMetaprojectItemData) obj;
+        return getMetaproject().getId().equals(other.getMetaproject().getId());
+    }
+
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/widget/MetaprojectTreeEntityItemWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/widget/MetaprojectTreeEntityItemWidget.java
new file mode 100644
index 0000000000000000000000000000000000000000..b212b8c1c89b800a4fea2f45312d5a0bddbae971
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/widget/MetaprojectTreeEntityItemWidget.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.widget;
+
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.ui.Widget;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.LinkRenderer;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.LinkExtractor;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.listener.OpenEntityDetailsTabHelper;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.model.MetaprojectTreeEntityItemData;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.WidgetUtils;
+
+/**
+ * @author pkupczyk
+ */
+public class MetaprojectTreeEntityItemWidget extends MetaprojectTreeItemWidget
+{
+
+    public MetaprojectTreeEntityItemWidget(final IViewContext<?> viewContext,
+            final MetaprojectTreeEntityItemData model)
+    {
+        super(viewContext);
+
+        ClickHandler listener = new ClickHandler()
+            {
+                @Override
+                public void onClick(ClickEvent event)
+                {
+                    OpenEntityDetailsTabHelper.open(viewContext, model.getEntity().getEntityKind(),
+                            model.getEntity().getPermId(),
+                            WidgetUtils.ifSpecialKeyPressed(event.getNativeEvent()));
+                }
+            };
+
+        Widget link =
+                LinkRenderer.getLinkWidget(model.getEntity().getIdentifier(), listener,
+                        LinkExtractor.tryExtract(model.getEntity()));
+
+        initWidget(link);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/widget/MetaprojectTreeEntityKindItemWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/widget/MetaprojectTreeEntityKindItemWidget.java
new file mode 100644
index 0000000000000000000000000000000000000000..c3a393f0700f82929708c885fe3911601d93f65d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/widget/MetaprojectTreeEntityKindItemWidget.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.widget;
+
+import com.google.gwt.user.client.ui.InlineLabel;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.model.MetaprojectTreeEntityKindItemData;
+
+/**
+ * @author pkupczyk
+ */
+public class MetaprojectTreeEntityKindItemWidget extends MetaprojectTreeItemWidget
+{
+
+    public MetaprojectTreeEntityKindItemWidget(IViewContext<?> viewContext,
+            MetaprojectTreeEntityKindItemData model)
+    {
+        super(viewContext);
+
+        initWidget(new InlineLabel(model.getEntityKind().name() + " (" + model.getEntityCount()
+                + ")"));
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/widget/MetaprojectTreeItemWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/widget/MetaprojectTreeItemWidget.java
new file mode 100644
index 0000000000000000000000000000000000000000..92d11fc9f3c7f622a8804595ea0f1afbaabe1947
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/widget/MetaprojectTreeItemWidget.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.widget;
+
+import com.google.gwt.user.client.ui.Composite;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+
+/**
+ * @author pkupczyk
+ */
+public abstract class MetaprojectTreeItemWidget extends Composite
+{
+
+    private IViewContext<?> viewContext;
+
+    private boolean selected;
+
+    public MetaprojectTreeItemWidget(IViewContext<?> viewContext)
+    {
+        this.viewContext = viewContext;
+    }
+
+    public void setSelected(boolean selected)
+    {
+        if (this.selected != selected)
+        {
+            this.selected = selected;
+            onSelectedChange();
+        }
+    }
+
+    public boolean isSelected()
+    {
+        return selected;
+    }
+
+    protected void onSelectedChange()
+    {
+
+    }
+
+    public IViewContext<?> getViewContext()
+    {
+        return viewContext;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/widget/MetaprojectTreeMetaprojectItemWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/widget/MetaprojectTreeMetaprojectItemWidget.java
new file mode 100644
index 0000000000000000000000000000000000000000..727523ba91a35da7501cb788aa910ac168c55cb8
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/metaproject/tree/widget/MetaprojectTreeMetaprojectItemWidget.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.widget;
+
+import com.google.gwt.event.dom.client.MouseOutEvent;
+import com.google.gwt.event.dom.client.MouseOutHandler;
+import com.google.gwt.event.dom.client.MouseOverEvent;
+import com.google.gwt.event.dom.client.MouseOverHandler;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.FocusPanel;
+import com.google.gwt.user.client.ui.InlineLabel;
+import com.google.gwt.user.client.ui.Widget;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.metaproject.tree.model.MetaprojectTreeMetaprojectItemData;
+
+/**
+ * @author pkupczyk
+ */
+public class MetaprojectTreeMetaprojectItemWidget extends MetaprojectTreeItemWidget
+{
+
+    private Widget link;
+
+    public MetaprojectTreeMetaprojectItemWidget(IViewContext<?> viewContext,
+            MetaprojectTreeMetaprojectItemData model)
+    {
+        super(viewContext);
+
+        // TODO make a real link that opens a metaproject detail view
+        link = new InlineLabel(viewContext.getMessage(Dict.METAPROJECT_TREE_INFO_LINK));
+        link.setVisible(isSelected());
+
+        FlowPanel panel = new FlowPanel();
+        panel.add(new InlineLabel(model.getMetaproject().getName() + " "));
+        panel.add(link);
+
+        FocusPanel focusPanel = new FocusPanel();
+        focusPanel.add(panel);
+        focusPanel.addMouseOverHandler(new MouseOverHandler()
+            {
+                @Override
+                public void onMouseOver(MouseOverEvent event)
+                {
+                    link.setVisible(true);
+                }
+            });
+        focusPanel.addMouseOutHandler(new MouseOutHandler()
+            {
+                @Override
+                public void onMouseOut(MouseOutEvent event)
+                {
+                    link.setVisible(isSelected());
+                }
+            });
+
+        initWidget(focusPanel);
+    }
+
+    @Override
+    protected void onSelectedChange()
+    {
+        link.setVisible(isSelected());
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
index d05cb4e2dee55783a20f26f36a5dcb944abf3ef7..dea297251552945c8d4e897732753b18d516f473 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -111,6 +112,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.server.translator.UserFailure
 import ch.systemsx.cisd.openbis.generic.client.web.server.util.TSVRenderer;
 import ch.systemsx.cisd.openbis.generic.shared.ICommonServer;
 import ch.systemsx.cisd.openbis.generic.shared.IServer;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.metaproject.MetaprojectTechIdId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolder;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWithPermId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IIdHolder;
@@ -161,6 +163,9 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignments;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsCount;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAuthorizationGroup;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewColumnOrFilter;
@@ -698,6 +703,30 @@ public final class CommonClientService extends AbstractClientService implements
         return listEntities(metaprojectProvider, criteria);
     }
 
+    @Override
+    public List<MetaprojectAssignmentsCount> listMetaprojectAssignmentsCounts()
+            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
+    {
+        return commonServer.listMetaprojectAssignmentsCounts(getSessionToken());
+    }
+
+    @Override
+    public MetaprojectAssignments getMetaprojectAssignments(Long metaprojectId,
+            MetaprojectAssignmentsFetchOption[] fetchOptions)
+            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
+    {
+        EnumSet<MetaprojectAssignmentsFetchOption> fetchOptionsSet =
+                EnumSet.noneOf(MetaprojectAssignmentsFetchOption.class);
+
+        for (MetaprojectAssignmentsFetchOption fetchOption : fetchOptions)
+        {
+            fetchOptionsSet.add(fetchOption);
+        }
+
+        return commonServer.getMetaprojectAssignments(getSessionToken(), new MetaprojectTechIdId(
+                metaprojectId), fetchOptionsSet);
+    }
+
     @Override
     public List<AuthorizationGroup> listAuthorizationGroups()
             throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
index 6ecf7dd92d3d44104c5b0640fc18059d696a6951..c29ceb23f3534a5037f7125a95fb9a5fceea265a 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.EnumMap;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
@@ -207,6 +208,8 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialTypePropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignments;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsCount;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAuthorizationGroup;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewColumnOrFilter;
@@ -3592,10 +3595,51 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         return MetaprojectTranslator.translate(metaprojectPEs);
     }
 
+    @Override
+    public List<MetaprojectAssignmentsCount> listMetaprojectAssignmentsCounts(String sessionToken)
+    {
+        IMetaprojectDAO metaprojectDAO = getDAOFactory().getMetaprojectDAO();
+
+        List<Metaproject> metaprojects = listMetaprojects(sessionToken);
+        List<MetaprojectAssignmentsCount> counts =
+                new ArrayList<MetaprojectAssignmentsCount>(metaprojects.size());
+
+        for (Metaproject metaproject : metaprojects)
+        {
+            MetaprojectAssignmentsCount count = new MetaprojectAssignmentsCount();
+            count.setMetaproject(metaproject);
+
+            count.setExperimentCount(metaprojectDAO.getMetaprojectAssignmentsCount(
+                    metaproject.getId(),
+                    ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind.EXPERIMENT));
+            count.setSampleCount(metaprojectDAO.getMetaprojectAssignmentsCount(metaproject.getId(),
+                    ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind.SAMPLE));
+            count.setDataSetCount(metaprojectDAO.getMetaprojectAssignmentsCount(
+                    metaproject.getId(),
+                    ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind.DATA_SET));
+            count.setMaterialCount(metaprojectDAO.getMetaprojectAssignmentsCount(
+                    metaproject.getId(),
+                    ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind.MATERIAL));
+
+            counts.add(count);
+        }
+
+        return counts;
+    }
+
     @Override
     @RolesAllowed(RoleWithHierarchy.SPACE_USER)
     public MetaprojectAssignments getMetaprojectAssignments(String sessionToken,
             IMetaprojectId metaprojectId)
+    {
+        return getMetaprojectAssignments(sessionToken, metaprojectId,
+                EnumSet.allOf(MetaprojectAssignmentsFetchOption.class));
+    }
+
+    @Override
+    @RolesAllowed(RoleWithHierarchy.SPACE_USER)
+    public MetaprojectAssignments getMetaprojectAssignments(String sessionToken,
+            IMetaprojectId metaprojectId, EnumSet<MetaprojectAssignmentsFetchOption> fetchOptions)
     {
         if (metaprojectId == null)
         {
@@ -3625,45 +3669,64 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         List<ExternalData> dataSets = new ArrayList<ExternalData>();
         List<Material> materials = new ArrayList<Material>();
 
-        for (MetaprojectAssignmentPE metaprojectAssignment : metaprojectPE.getAssignments())
+        if (fetchOptions.contains(MetaprojectAssignmentsFetchOption.EXPERIMENTS))
         {
-            if (metaprojectAssignment.getExperiment() != null)
+            for (MetaprojectAssignmentPE metaprojectAssignmentPE : getMetaprojectAssignments(
+                    metaprojectPE, EntityKind.EXPERIMENT))
             {
-                if (authorizationUtils.canAccessExperiment(metaprojectAssignment.getExperiment()))
+                if (authorizationUtils.canAccessExperiment(metaprojectAssignmentPE.getExperiment()))
                 {
                     experiments.add(ExperimentTranslator.translate(
-                            metaprojectAssignment.getExperiment(), baseIndexURL, null,
+                            metaprojectAssignmentPE.getExperiment(), baseIndexURL, null,
                             LoadableFields.PROPERTIES));
                 } else
                 {
                     experiments.add(ExperimentTranslator.translateWithoutRevealingData(
-                            metaprojectAssignment.getExperiment(), null));
+                            metaprojectAssignmentPE.getExperiment(), null));
                 }
-            } else if (metaprojectAssignment.getSample() != null)
+            }
+        }
+
+        if (fetchOptions.contains(MetaprojectAssignmentsFetchOption.SAMPLES))
+        {
+            for (MetaprojectAssignmentPE metaprojectAssignmentPE : getMetaprojectAssignments(
+                    metaprojectPE, EntityKind.SAMPLE))
             {
-                if (authorizationUtils.canAccessSample(metaprojectAssignment.getSample()))
+                if (authorizationUtils.canAccessSample(metaprojectAssignmentPE.getSample()))
                 {
-                    samples.add(SampleTranslator.translate(metaprojectAssignment.getSample(),
+                    samples.add(SampleTranslator.translate(metaprojectAssignmentPE.getSample(),
                             baseIndexURL, null));
                 } else
                 {
                     samples.add(SampleTranslator
-                            .translateWithoutRevealingData(metaprojectAssignment.getSample()));
+                            .translateWithoutRevealingData(metaprojectAssignmentPE.getSample()));
                 }
-            } else if (metaprojectAssignment.getDataSet() != null)
+            }
+        }
+
+        if (fetchOptions.contains(MetaprojectAssignmentsFetchOption.DATA_SETS))
+        {
+            for (MetaprojectAssignmentPE metaprojectAssignmentPE : getMetaprojectAssignments(
+                    metaprojectPE, EntityKind.DATA_SET))
             {
-                if (authorizationUtils.canAccessDataSet(metaprojectAssignment.getDataSet()))
+                if (authorizationUtils.canAccessDataSet(metaprojectAssignmentPE.getDataSet()))
                 {
-                    dataSets.add(DataSetTranslator.translate(metaprojectAssignment.getDataSet(),
+                    dataSets.add(DataSetTranslator.translate(metaprojectAssignmentPE.getDataSet(),
                             baseIndexURL, null));
                 } else
                 {
                     dataSets.add(DataSetTranslator
-                            .translateWithoutRevealingData(metaprojectAssignment.getDataSet()));
+                            .translateWithoutRevealingData(metaprojectAssignmentPE.getDataSet()));
                 }
-            } else if (metaprojectAssignment.getMaterial() != null)
+            }
+        }
+
+        if (fetchOptions.contains(MetaprojectAssignmentsFetchOption.MATERIALS))
+        {
+            for (MetaprojectAssignmentPE metaprojectAssignmentPE : getMetaprojectAssignments(
+                    metaprojectPE, EntityKind.MATERIAL))
             {
-                materials.add(MaterialTranslator.translate(metaprojectAssignment.getMaterial(),
+                materials.add(MaterialTranslator.translate(metaprojectAssignmentPE.getMaterial(),
                         null));
             }
         }
@@ -3813,6 +3876,13 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         return MetaprojectTranslator.translate(metaprojectPE);
     }
 
+    private Collection<MetaprojectAssignmentPE> getMetaprojectAssignments(
+            MetaprojectPE metaproject, EntityKind entityKind)
+    {
+        return getDAOFactory().getMetaprojectDAO().listMetaprojectAssignments(metaproject.getId(),
+                DtoConverters.convertEntityKind(entityKind));
+    }
+
     private AuthorizationServiceUtils getAuthorizationService(Session session)
     {
         return new AuthorizationServiceUtils(getDAOFactory(), session.tryGetPerson());
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
index 38303d6adb560b60ea6ecbe8d7ab6f31ac9dd8b1..9e867816de5ce3bd596e31ba789d479e3193d876 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
@@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.server;
 
 import java.util.Collection;
 import java.util.Date;
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -82,6 +83,8 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignments;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsCount;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAuthorizationGroup;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewColumnOrFilter;
@@ -649,8 +652,7 @@ final class CommonServerLogger extends AbstractServerLogger implements ICommonSe
             DataSetRelatedEntities entities, boolean withDetails, String userId)
     {
         logAccess(sessionToken, "list_related_datasets_on_behalf_of_user", "WITH_DETAILS(%s)",
-                "WITH_USER(%s)",
-                withDetails, userId);
+                "WITH_USER(%s)", withDetails, userId);
         return null;
     }
 
@@ -1512,6 +1514,22 @@ final class CommonServerLogger extends AbstractServerLogger implements ICommonSe
         return null;
     }
 
+    @Override
+    public List<MetaprojectAssignmentsCount> listMetaprojectAssignmentsCounts(String sessionToken)
+    {
+        logAccess(sessionToken, "listMetaprojectAssignmentsCounts");
+        return null;
+    }
+
+    @Override
+    public MetaprojectAssignments getMetaprojectAssignments(String sessionToken,
+            IMetaprojectId metaprojectId, EnumSet<MetaprojectAssignmentsFetchOption> fetchOptions)
+    {
+        logAccess(sessionToken, "getMetaprojectAssignments",
+                "METAPROJECT_ID(%s) FETCH_OPTIONS(%s)", metaprojectId, fetchOptions);
+        return null;
+    }
+
     @Override
     public MetaprojectAssignments getMetaprojectAssignments(String sessionToken,
             IMetaprojectId metaprojectId)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMetaprojectDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMetaprojectDAO.java
index 7b62a05ea4113ac9ba1cf113cdc002751d93294c..1b27fdf01e8aab0ae6ce468fc8abbdabce8d8e40 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMetaprojectDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IMetaprojectDAO.java
@@ -59,4 +59,17 @@ public interface IMetaprojectDAO extends IGenericDAO<MetaprojectPE>
     public Collection<MetaprojectAssignmentPE> listMetaprojectAssignmentsForEntities(
             PersonPE owner, Collection<? extends IEntityInformationWithPropertiesHolder> entities,
             EntityKind entityKind);
+
+    /**
+     * Lists assignments for the given entity kind and metaproject.
+     */
+    Collection<MetaprojectAssignmentPE> listMetaprojectAssignments(Long metaprojectId,
+            EntityKind entityKind);
+
+    /**
+     * Returns a map with counts of assignments for different entity kinds for the given
+     * metaproject.
+     */
+    public int getMetaprojectAssignmentsCount(Long metaprojectId, EntityKind entityKind);
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MetaprojectDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MetaprojectDAO.java
index 8c681123a1db02ea605174180078da379b59b34d..21675488f37a05d06f48da76535f978b268032ad 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MetaprojectDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/MetaprojectDAO.java
@@ -26,6 +26,7 @@ import org.apache.log4j.Logger;
 import org.hibernate.SessionFactory;
 import org.hibernate.criterion.DetachedCriteria;
 import org.hibernate.criterion.Order;
+import org.hibernate.criterion.Projections;
 import org.hibernate.criterion.Restrictions;
 import org.springframework.orm.hibernate3.HibernateTemplate;
 
@@ -163,4 +164,46 @@ public class MetaprojectDAO extends AbstractGenericEntityDAO<MetaprojectPE> impl
 
         return assignments;
     }
+
+    @Override
+    public Collection<MetaprojectAssignmentPE> listMetaprojectAssignments(Long metaprojectId,
+            EntityKind entityKind)
+    {
+        final DetachedCriteria criteria = DetachedCriteria.forClass(MetaprojectAssignmentPE.class);
+        criteria.createAlias("metaproject", "m");
+        criteria.add(Restrictions.eq("m.id", metaprojectId));
+        criteria.add(Restrictions.isNotNull(entityKind.getLabel()));
+        final List<MetaprojectAssignmentPE> assignments =
+                cast(getHibernateTemplate().findByCriteria(criteria));
+
+        if (operationLog.isDebugEnabled())
+        {
+            operationLog.debug(String.format("%s(%s, %s): %d metaproject(s) have been found.",
+                    MethodUtils.getCurrentMethod().getName(), metaprojectId, entityKind,
+                    assignments.size()));
+        }
+
+        return assignments;
+    }
+
+    @Override
+    public int getMetaprojectAssignmentsCount(Long metaprojectId, EntityKind entityKind)
+    {
+        final DetachedCriteria criteria = DetachedCriteria.forClass(MetaprojectAssignmentPE.class);
+        criteria.createAlias("metaproject", "m");
+        criteria.add(Restrictions.eq("m.id", metaprojectId));
+        criteria.add(Restrictions.isNotNull(entityKind.getLabel()));
+        criteria.setProjection(Projections.rowCount());
+
+        Number count = (Number) getHibernateTemplate().findByCriteria(criteria).get(0);
+        
+        if (operationLog.isDebugEnabled())
+        {
+            operationLog.debug(String.format("%s(%s, %s): %d metaproject assignments have been found.",
+                    MethodUtils.getCurrentMethod().getName(), metaprojectId, entityKind,
+                    count));
+        }
+        
+        return count.intValue();
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
index 101aee494af3cdb904f7e9275c70018d19ff2a1d..27456fc4d5855e2127d805fb8de7fc05f6bc1647 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
@@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.shared;
 
 import java.util.Collection;
 import java.util.Date;
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -80,6 +81,8 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignments;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsCount;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MetaprojectAssignmentsFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAuthorizationGroup;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewColumnOrFilter;
@@ -1374,12 +1377,25 @@ public interface ICommonServer extends IServer
     @Transactional(readOnly = true)
     public List<Metaproject> listMetaprojects(String sessionToken);
 
+    /**
+     * Lists all metaproject assignments counts for given user.
+     */
+    @Transactional(readOnly = true)
+    public List<MetaprojectAssignmentsCount> listMetaprojectAssignmentsCounts(String sessionToken);
+
     /**
      * Returns object containing all entities assigned to given metaproject.
      */
     @Transactional(readOnly = true)
     public MetaprojectAssignments getMetaprojectAssignments(String sessionToken,
-            IMetaprojectId metaproject);
+            IMetaprojectId metaprojectId);
+
+    /**
+     * Returns object containing chosen entities assigned to given metaproject.
+     */
+    @Transactional(readOnly = true)
+    public MetaprojectAssignments getMetaprojectAssignments(String sessionToken,
+            IMetaprojectId metaprojectId, EnumSet<MetaprojectAssignmentsFetchOption> fetchOptions);
 
     /**
      * Adds specified entities to given metaproject.
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MetaprojectAssignmentsCount.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MetaprojectAssignmentsCount.java
new file mode 100644
index 0000000000000000000000000000000000000000..82090d8320ce503f470bc0881857be665c1ca8a0
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MetaprojectAssignmentsCount.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.shared.basic.dto;
+
+import java.io.Serializable;
+
+/**
+ * @author pkupczyk
+ */
+public class MetaprojectAssignmentsCount implements Serializable
+{
+
+    private static final long serialVersionUID = ServiceVersionHolder.VERSION;
+
+    private Metaproject metaproject;
+
+    private int experimentCount;
+
+    private int sampleCount;
+
+    private int dataSetCount;
+
+    private int materialCount;
+
+    public Metaproject getMetaproject()
+    {
+        return metaproject;
+    }
+
+    public void setMetaproject(Metaproject metaproject)
+    {
+        this.metaproject = metaproject;
+    }
+
+    public int getExperimentCount()
+    {
+        return experimentCount;
+    }
+
+    public void setExperimentCount(int experimentCount)
+    {
+        this.experimentCount = experimentCount;
+    }
+
+    public int getSampleCount()
+    {
+        return sampleCount;
+    }
+
+    public void setSampleCount(int sampleCount)
+    {
+        this.sampleCount = sampleCount;
+    }
+
+    public int getDataSetCount()
+    {
+        return dataSetCount;
+    }
+
+    public void setDataSetCount(int dataSetCount)
+    {
+        this.dataSetCount = dataSetCount;
+    }
+
+    public int getMaterialCount()
+    {
+        return materialCount;
+    }
+
+    public void setMaterialCount(int materialCount)
+    {
+        this.materialCount = materialCount;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MetaprojectAssignmentsFetchOption.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MetaprojectAssignmentsFetchOption.java
new file mode 100644
index 0000000000000000000000000000000000000000..6c08407e8311a9115c779f11d8af21970218158f
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/MetaprojectAssignmentsFetchOption.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed 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 ch.systemsx.cisd.openbis.generic.shared.basic.dto;
+
+/**
+ * @author pkupczyk
+ */
+public enum MetaprojectAssignmentsFetchOption implements FetchOption
+{
+
+    EXPERIMENTS, SAMPLES, DATA_SETS, MATERIALS;
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
index 91889a4d153e280c156417d073b3046ae19e3ab4..eb3cd2e062207afe8bd6ac0f90be8c44ef8e674f 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
@@ -474,6 +474,8 @@ var common = {
   PROJECT_MENU_BROWSE: "Projects",
   PROJECT_MENU_NEW: "Project",
   
+  METAPROJECT_MENU_BROWSE: "Metaprojects",
+  
   menu_property_types: "Metadata",
   PROPERTY_TYPES_MENU_BROWSE_PROPERTY_TYPES: "Browse Property Types",
   PROPERTY_TYPES_MENU_BROWSE_ASSIGNMENTS: "Browse Assignments",
@@ -605,6 +607,7 @@ var common = {
   HELP__TABLE_SETTINGS__CUSTOM_FILTER__EDIT: "Add or Edit Custom Filter",
   HELP__EXPORT_DATA__ACTION: "Data Exporting",
   HELP__PERFORM_COMPUTATION__ACTION: "Performing Computations on Data Sets",
+  HELP__METAPROJECT__BROWSE: "Metaproject Browser",
     
   //
   // User Settings Dialog
@@ -723,6 +726,20 @@ var common = {
  //
  project_browser: "Project Browser",
 
+ //
+ // Metaproject Tree
+ //
+ 
+ metaproject_tree_column_header: "Metaproject / Entity Kind / Entity",
+ metaproject_tree_info_link: "(info)",
+ 
+ //
+ // Metaproject Browser
+ //
+ metaproject_browser: "Metaproject Browser",
+ metaproject_browser_tree_title: "Metaprojects",
+ metaproject_browser_tree_tooltip: "Click on a row with an entity type (i.e. Experiments, Samples, Data Sets, Materials) to see entities of that type that belong to the given metaproject.",
+
  //
  // Project Registration
  //