diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/GenericViewModel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/GenericViewModel.java
index 88f1e42392eb045c001c3e91244a0eef3e93caab..6463ad8f238b0fb253e13b5240d55a002fcf7496 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/GenericViewModel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/GenericViewModel.java
@@ -83,7 +83,8 @@ public class GenericViewModel
 
     public boolean isDisplaySettingsSaving()
     {
-        return isAnonymousLogin() == false && ViewMode.NORMAL.equals(getViewMode());
+        return isAnonymousLogin() == false
+                && (ViewMode.NORMAL.equals(getViewMode()) || ViewMode.GRID.equals(getViewMode()));
     }
 
     public void setAnonymousAllowed(boolean anonymousAllowed)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/TypedTableGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/TypedTableGrid.java
index 83e7e57b7496f71b155f951c860721c3a8f1c68c..444ac0148eb5e920a2225d9e1107b3b32714fa51 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/TypedTableGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/TypedTableGrid.java
@@ -1529,6 +1529,14 @@ public abstract class TypedTableGrid<T extends Serializable> extends LayoutConta
     {
         int id = log("refresh (refreshColumnsDefinition=" + refreshColumnsDefinition + ")");
         pagingToolbar.updateDefaultRefreshButton(false);
+
+        SortInfo sortInfo = getGridSortInfo();
+        if (sortInfo != null)
+        {
+            pagingLoader.setSortField(sortInfo.getSortField());
+            pagingLoader.setSortDir(translate(sortInfo.getSortDir()));
+        }
+
         debug("clean cache for refresh");
         this.refreshCallback = createRefreshCallback(externalRefreshCallbackOrNull);
         if (columnDefinitions == null || refreshColumnsDefinition)
@@ -2740,6 +2748,8 @@ public abstract class TypedTableGrid<T extends Serializable> extends LayoutConta
                                 customColumnsMetadataProvider
                                         .setCustomColumnsMetadata(customColumnMetadata);
                                 recreateColumnModelAndRefreshColumnsWithFilters();
+
+                                saveColumnDisplaySettings();
                             }
                             callback.onSuccess(resultSet);
                         }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/aggregation/AggregationServicePanel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/aggregation/AggregationServicePanel.java
index bdea6d34e4057c3b8eb7124078e80515fe418798..f788ea36e5c3d342cc1579810100af6d8e7350c3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/aggregation/AggregationServicePanel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/aggregation/AggregationServicePanel.java
@@ -20,6 +20,13 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import com.extjs.gxt.ui.client.widget.ContentPanel;
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
+import com.extjs.gxt.ui.client.widget.layout.FitLayout;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.HTML;
+
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.locator.ViewLocator;
@@ -30,13 +37,6 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableModelReferenc
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ReportingPluginType;
 
-import com.extjs.gxt.ui.client.widget.ContentPanel;
-import com.extjs.gxt.ui.client.widget.LayoutContainer;
-import com.extjs.gxt.ui.client.widget.layout.FitLayout;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.ui.HTML;
-
 /**
  * A panel that shows the results of an aggregation service.
  * 
@@ -48,6 +48,8 @@ public class AggregationServicePanel extends ContentPanel
 
     private static final String DSS_CODE_PARAM = "dss";
 
+    private static final String DISPLAY_SETTINGS_ID = "displaySettingsId";
+
     private static class AggregationServiceGeneratedAction implements
             IOnReportComponentGeneratedAction
     {
@@ -65,7 +67,7 @@ public class AggregationServicePanel extends ContentPanel
             layoutContainer.add(reportComponent.getComponent());
             layoutContainer.layout();
         }
-    };
+    }
 
     private final IViewContext<ICommonClientServiceAsync> viewContext;
 
@@ -75,6 +77,8 @@ public class AggregationServicePanel extends ContentPanel
 
     private final String dataStoreCode;
 
+    private final String displaySettingsId;
+
     public AggregationServicePanel(IViewContext<ICommonClientServiceAsync> viewContext,
             String idPrefix, ViewLocator viewLocator)
     {
@@ -84,6 +88,7 @@ public class AggregationServicePanel extends ContentPanel
         this.viewLocator = viewLocator;
         serviceKey = viewLocator.getParameters().get(SERVICE_KEY_PARAM);
         dataStoreCode = viewLocator.getParameters().get(DSS_CODE_PARAM);
+        displaySettingsId = viewLocator.getParameters().get(DISPLAY_SETTINGS_ID);
 
         if (areRequiredParametersSpecified())
         {
@@ -146,14 +151,21 @@ public class AggregationServicePanel extends ContentPanel
             {
                 continue;
             }
+            if (DISPLAY_SETTINGS_ID.equals(entry.getKey()))
+            {
+                continue;
+            }
             parameterMap.put(entry.getKey(), entry.getValue());
         }
         DatastoreServiceDescription description =
                 DatastoreServiceDescription.reporting(serviceKey, "", new String[0], dataStoreCode,
                         ReportingPluginType.AGGREGATION_TABLE_MODEL);
 
+        String notNullDisplaySettingsId =
+                displaySettingsId != null ? displaySettingsId : serviceKey;
+
         AsyncCallback<TableModelReference> callback =
-                ReportGeneratedCallback.create(viewContext, description,
+                ReportGeneratedCallback.create(viewContext, description, notNullDisplaySettingsId,
                         new AggregationServiceGeneratedAction(this));
 
         viewContext.getCommonService().createReportFromAggregationService(description,
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetReportGenerator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetReportGenerator.java
index f907fb7e81719111cf51f613402cb759cb9b272e..bdecaeb4f7f215c5e6a616bfac7a305c6d497667 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetReportGenerator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetReportGenerator.java
@@ -65,7 +65,7 @@ public class DataSetReportGenerator
             IOnReportComponentGeneratedAction action)
     {
         AsyncCallback<TableModelReference> callback =
-                ReportGeneratedCallback.create(viewContext, service, action);
+                ReportGeneratedCallback.create(viewContext, service, service.getKey(), action);
         viewContext.getService().createReportFromDatasets(service, criteria, callback);
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGeneratedCallback.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGeneratedCallback.java
index 6d5fff5d1e694cb8c7d85ae7de03da6e521cba93..d87437a1a033575456e245030f8fcfbf4655ce51 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGeneratedCallback.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGeneratedCallback.java
@@ -44,22 +44,25 @@ public class ReportGeneratedCallback extends AbstractAsyncCallback<TableModelRef
 
     private final IReportInformationProvider reportInformationProvider;
 
+    private final String displaySettingsId;
+
     public static AsyncCallback<TableModelReference> create(
             IViewContext<ICommonClientServiceAsync> viewContext,
-            IReportInformationProvider reportInformationProvider,
+            IReportInformationProvider reportInformationProvider, String displaySettingsId,
             IOnReportComponentGeneratedAction action)
     {
         return AsyncCallbackWithProgressBar.decorate(new ReportGeneratedCallback(viewContext,
-                reportInformationProvider, action), "Generating the report...");
+                reportInformationProvider, displaySettingsId, action), "Generating the report...");
     }
 
     private ReportGeneratedCallback(IViewContext<ICommonClientServiceAsync> viewContext,
-            IReportInformationProvider reportInformationProvider,
+            IReportInformationProvider reportInformationProvider, String displaySettingsId,
             IOnReportComponentGeneratedAction action)
     {
         super(viewContext);
         this.localViewContext = viewContext;
         this.reportInformationProvider = reportInformationProvider;
+        this.displaySettingsId = displaySettingsId;
         this.action = action;
     }
 
@@ -67,7 +70,8 @@ public class ReportGeneratedCallback extends AbstractAsyncCallback<TableModelRef
     protected void process(final TableModelReference tableModelReference)
     {
         final IDisposableComponent reportComponent =
-                ReportGrid.create(localViewContext, tableModelReference, reportInformationProvider);
+                ReportGrid.create(localViewContext, tableModelReference, reportInformationProvider,
+                        displaySettingsId);
         action.execute(reportComponent);
         if (StringUtils.isBlank(tableModelReference.tryGetMessage()) == false)
         {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGrid.java
index ab77b40d6e7c2863f04e9c8b7b4950397bc68bf3..bc4b7cfbe0c4d50010eef6ef680fc470a465f2f8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/report/ReportGrid.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.report;
 
+import java.util.HashSet;
 import java.util.Set;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
@@ -30,10 +31,13 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSetFetchConf
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableModelReference;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TypedTableResultSet;
+import ch.systemsx.cisd.openbis.generic.shared.basic.IColumnDefinition;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IReportInformationProvider;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ReportRowModel;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelColumnHeader;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TypedTableGridColumnDefinition;
 
 /**
  * @author Franz-Josef Elmer
@@ -45,10 +49,11 @@ public class ReportGrid extends TypedTableGrid<ReportRowModel>
 
     public static IDisposableComponent create(
             final IViewContext<ICommonClientServiceAsync> viewContext,
-            TableModelReference tableModelReference, IReportInformationProvider infoProvider)
+            TableModelReference tableModelReference, IReportInformationProvider infoProvider,
+            String displaySettingsId)
     {
         final ReportGrid grid =
-                new ReportGrid(viewContext, tableModelReference, infoProvider.getKey(),
+                new ReportGrid(viewContext, tableModelReference, displaySettingsId,
                         infoProvider.getDownloadURL());
         return grid.asDisposableWithoutToolbar();
     }
@@ -60,23 +65,26 @@ public class ReportGrid extends TypedTableGrid<ReportRowModel>
 
     private final String resultSetKey;
 
-    private final String reportKind;
+    private final String displaySettingsId;
+
+    private final TableModelReference tableModelReference;
 
     private ReportGrid(IViewContext<ICommonClientServiceAsync> viewContext,
-            TableModelReference tableModelReference, String reportKind, String downloadURL)
+            TableModelReference tableModelReference, String displaySettingsId, String downloadURL)
     {
         super(viewContext, BROWSER_ID, true, DisplayTypeIDGenerator.DATA_SET_REPORTING_GRID);
         setDownloadURL(downloadURL);
         setId(BROWSER_ID);
+        this.tableModelReference = tableModelReference;
         this.resultSetKey = tableModelReference.getResultSetKey();
-        this.reportKind = reportKind;
+        this.displaySettingsId = displaySettingsId;
         updateDefaultRefreshButton();
     }
 
     @Override
     public String getGridDisplayTypeID()
     {
-        return createGridDisplayTypeID(reportKind);
+        return createGridDisplayTypeID(displaySettingsId);
     }
 
     @Override
@@ -88,6 +96,21 @@ public class ReportGrid extends TypedTableGrid<ReportRowModel>
         // The custom columns should be recomputed.
         resultSetConfig.setCacheConfig(ResultSetFetchConfig
                 .createFetchFromCacheAndRecompute(resultSetKey));
+
+        Set<IColumnDefinition<TableModelRowWithObject<ReportRowModel>>> availableColumns =
+                new HashSet<IColumnDefinition<TableModelRowWithObject<ReportRowModel>>>();
+
+        if (tableModelReference.getHeader() != null)
+        {
+            for (TableModelColumnHeader header : tableModelReference.getHeader())
+            {
+                availableColumns.add(new TypedTableGridColumnDefinition<ReportRowModel>(header,
+                        null, null, null));
+            }
+        }
+
+        resultSetConfig.setAvailableColumns(availableColumns);
+
         viewContext.getService().listReport(resultSetConfig, callback);
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrl.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrl.java
index 8929bc9c2bc836b09228aa8d726d3ed7ea811294..12f4fd75754539c0178d36e53ed6efc8ef9198a7 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrl.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrl.java
@@ -51,6 +51,7 @@ public class WebAppUrl
 
         builder =
                 new URLMethodWithParameters(openbisProtocol + "//" + openbisHost + "/" + webAppCode);
+        builder.addParameter(WebAppUrlParameter.WEBAPP_CODE.getName(), webAppCode);
         builder.addParameter(WebAppUrlParameter.SESSION_ID.getName(), sessionId);
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlParameter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlParameter.java
index ad8f65a7574a888f773ad51f78c60cda183f7983..09ee0aca86ad7cf62c8f34ad1e6cb69f4ec5108f 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlParameter.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlParameter.java
@@ -24,8 +24,9 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.webapp
 public enum WebAppUrlParameter
 {
 
-    SESSION_ID("session-id"), ENTITY_KIND("entity-kind"), ENTITY_TYPE("entity-type"),
-    ENTITY_IDENTIFIER("entity-identifier"), ENTITY_PERM_ID("entity-perm-id");
+    WEBAPP_CODE("webapp-code"), SESSION_ID("session-id"), ENTITY_KIND("entity-kind"), ENTITY_TYPE(
+            "entity-type"), ENTITY_IDENTIFIER("entity-identifier"),
+    ENTITY_PERM_ID("entity-perm-id");
 
     private final String name;
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryEditor.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryEditor.java
index e13a47bb67545395a7551535586f619d03fc575a..f15ff750bb922ae40d73c76ea16f651e62058782 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryEditor.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryEditor.java
@@ -86,7 +86,9 @@ public class QueryEditor extends Dialog
 
     private static Button createCancelButton(IViewContext<?> viewContext, final Window window)
     {
-        return new Button(viewContext.getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.BUTTON_CANCEL),
+        return new Button(
+                viewContext
+                        .getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.BUTTON_CANCEL),
                 new SelectionListener<ButtonEvent>()
                     {
                         @Override
@@ -146,7 +148,9 @@ public class QueryEditor extends Dialog
             }
 
             add(form, new BorderLayoutData(LayoutRegion.CENTER));
-            addButton(new Button(viewContext.getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.BUTTON_SUBMIT),
+            addButton(new Button(
+                    viewContext
+                            .getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.BUTTON_SUBMIT),
                     new SelectionListener<ButtonEvent>()
                         {
                             @Override
@@ -216,14 +220,25 @@ public class QueryEditor extends Dialog
         setButtons("");
 
         nameField =
-                AbstractRegistrationDialog.createTextField(viewContext.getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.NAME), true);
+                AbstractRegistrationDialog
+                        .createTextField(
+                                viewContext
+                                        .getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.NAME),
+                                true);
         nameField.setMaxLength(200);
         descriptionField =
-                AbstractRegistrationDialog.createTextField(
-                        viewContext.getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.DESCRIPTION), false);
+                AbstractRegistrationDialog
+                        .createTextField(
+                                viewContext
+                                        .getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.DESCRIPTION),
+                                false);
         descriptionField.setMaxLength(GenericConstants.DESCRIPTION_2000);
         statementField = createStatementField();
-        isPublicField = new CheckBoxField(viewContext.getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.IS_PUBLIC), false);
+        isPublicField =
+                new CheckBoxField(
+                        viewContext
+                                .getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.IS_PUBLIC),
+                        false);
         queryDatabaseSelectionWidget =
                 new QueryDatabaseSelectionWidget(viewContext,
                         (queryOrNull != null) ? queryOrNull.getQueryDatabase() : null);
@@ -406,7 +421,9 @@ public class QueryEditor extends Dialog
     private Button createSaveButton(final FormPanel form, final IDelegatedAction refreshAction)
     {
         final Button button =
-                new Button(viewContext.getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.BUTTON_SAVE),
+                new Button(
+                        viewContext
+                                .getMessage(ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict.BUTTON_SAVE),
                         new SelectionListener<ButtonEvent>()
                             {
                                 @Override
@@ -515,12 +532,15 @@ public class QueryEditor extends Dialog
         QueryDatabase queryDatabase = queryDatabaseSelectionWidget.tryGetSelected();
         if (sqlStatement != null && sqlStatement.length() > 0 && queryDatabase != null)
         {
+            IReportInformationProvider reportInformation =
+                    createReportInformationProvider(sqlStatement);
+
             viewContext.getService().createQueryResultsReport(
                     queryDatabase,
                     sqlStatement,
                     parameterBindings,
                     ReportGeneratedCallback.create(viewContext.getCommonViewContext(),
-                            createReportInformationProvider(sqlStatement),
+                            reportInformation, reportInformation.getKey(),
                             createDisplayQueryResultsAction()));
         }
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryViewer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryViewer.java
index 2dd8c5fd01cf95099addc0dd96f95d6595532aa5..b89b98e0b9d07bab25df8b135b5e60b4cfe00d57 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryViewer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/web/client/application/module/QueryViewer.java
@@ -99,9 +99,13 @@ public class QueryViewer extends ContentPanel implements IDatabaseModificationOb
         {
             return;
         }
+
+        IReportInformationProvider reportInformation =
+                createReportInformationProvider(sqlQueryOrNull, queryIdOrNull);
+
         AsyncCallback<TableModelReference> callback =
                 ReportGeneratedCallback.create(viewContext.getCommonViewContext(),
-                        createReportInformationProvider(sqlQueryOrNull, queryIdOrNull),
+                        reportInformation, reportInformation.getKey(),
                         createDisplayQueryResultsAction());
         if (queryIdOrNull != null)
         {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/js/openbis.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/js/openbis.js
index c74b37249a0b22bba5e4dd1d2b522549c0d32049..1de93b624f739b5339b535b6c698f9a68bba86e5 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/js/openbis.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/resources/js/openbis.js
@@ -432,6 +432,7 @@ actionDeferrer.prototype.dependencyCompleted = function(key) {
  * Provides a context information for webapps that are embedded inside the OpenBIS UI.
  */
 function openbisWebAppContext(){
+	this.webappCode = this.getParameter("webapp-code");
 	this.sessionId = this.getParameter("session-id");
 	this.entityKind = this.getParameter("entity-kind");
 	this.entityType = this.getParameter("entity-type");
@@ -439,6 +440,10 @@ function openbisWebAppContext(){
 	this.entityPermId = this.getParameter("entity-perm-id");
 }
 
+openbisWebAppContext.prototype.getWebappCode = function(){
+	return this.webappCode;
+}
+
 openbisWebAppContext.prototype.getSessionId = function(){
 	return this.sessionId;
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlTest.java
index 788d6a2039fad35e3e567bd45a5b36407e2d07ec..76279ddf2ef4b57bae7a8c81cd24c3f6766a21b6 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/webapp/WebAppUrlTest.java
@@ -33,7 +33,9 @@ public class WebAppUrlTest
     public void testUrlWithoutParameters()
     {
         WebAppUrl url = new WebAppUrl("http:", "localhost:8888", "webapp1", "mysessionid");
-        Assert.assertEquals("http://localhost:8888/webapp1?session-id=mysessionid", url.toString());
+        Assert.assertEquals(
+                "http://localhost:8888/webapp1?webapp-code=webapp1&session-id=mysessionid",
+                url.toString());
     }
 
     @Test
@@ -44,7 +46,9 @@ public class WebAppUrlTest
         url.addEntityType(null);
         url.addEntityIdentifier(null);
         url.addEntityPermId(null);
-        Assert.assertEquals("http://localhost:8888/webapp1?session-id=mysessionid", url.toString());
+        Assert.assertEquals(
+                "http://localhost:8888/webapp1?webapp-code=webapp1&session-id=mysessionid",
+                url.toString());
     }
 
     @Test
@@ -56,7 +60,7 @@ public class WebAppUrlTest
         url.addEntityIdentifier("TEST_EXPERIMENT_IDENTIFIER");
         url.addEntityPermId("TEST_EXPERIMENT_PERM_ID");
         Assert.assertEquals(
-                "http://localhost:8888/webapp1?session-id=mysessionid&entity-kind=EXPERIMENT"
+                "http://localhost:8888/webapp1?webapp-code=webapp1&session-id=mysessionid&entity-kind=EXPERIMENT"
                         + "&entity-type=TEST_EXPERIMENT_TYPE&entity-identifier=TEST_EXPERIMENT_IDENTIFIER"
                         + "&entity-perm-id=TEST_EXPERIMENT_PERM_ID", url.toString());
     }
@@ -70,7 +74,7 @@ public class WebAppUrlTest
         url.addEntityIdentifier("TEST/EXPERIMENT/IDENTIFIER");
         url.addEntityPermId("TEST&EXPERIMENT&PERM&ID");
         Assert.assertEquals(
-                "http://localhost:8888/%28webapp1%29?session-id=%5Bmysessionid%5D&entity-kind=EXPERIMENT"
+                "http://localhost:8888/%28webapp1%29?webapp-code=%28webapp1%29&session-id=%5Bmysessionid%5D&entity-kind=EXPERIMENT"
                         + "&entity-type=TEST+EXPERIMENT+TYPE&entity-identifier=TEST%2FEXPERIMENT%2FIDENTIFIER"
                         + "&entity-perm-id=TEST%26EXPERIMENT%26PERM%26ID", url.toString());
     }