diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientService.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientService.java
index a299c9d8cc1bcabfb7c99afb07c54fcc2752134e..b38417ced37ce1b721752c36df152c8df21bb506 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientService.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientService.java
@@ -39,9 +39,9 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.AbundanceCol
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.DataSetProtein;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinByExperiment;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinInfo;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinRelatedSample;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSequence;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
 
 /**
  * * Service interface for the PhosphoNetX GWT client.
@@ -102,11 +102,11 @@ public interface IPhosphoNetXClientService extends IClientService
             TableExportCriteria<TableModelRowWithObject<DataSetProtein>> exportCriteria)
             throws UserFailureException;
 
-    public ResultSet<SampleWithPropertiesAndAbundance> listSamplesWithAbundanceByProtein(
+    public TypedTableResultSet<ProteinRelatedSample> listProteinRelatedSamplesByProtein(
             ListSampleAbundanceByProteinCriteria criteria) throws UserFailureException;
 
-    public String prepareExportSamplesWithAbundance(
-            TableExportCriteria<SampleWithPropertiesAndAbundance> exportCriteria)
+    public String prepareExportProteinRelatedSamples(
+            TableExportCriteria<TableModelRowWithObject<ProteinRelatedSample>> exportCriteria)
             throws UserFailureException;
 
     public TypedTableResultSet<Sample> listRawDataSamples(
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientServiceAsync.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientServiceAsync.java
index 84e9b6986a1b8f46950f745c6be9dcbd5924ce11..9d4d652f903c54191fd12290bbe2d8bcf6e0d346 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientServiceAsync.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/IPhosphoNetXClientServiceAsync.java
@@ -40,9 +40,9 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.AbundanceCol
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.DataSetProtein;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinByExperiment;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinInfo;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinRelatedSample;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSequence;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
 
 /**
  * @author Franz-Josef Elmer
@@ -116,13 +116,13 @@ public interface IPhosphoNetXClientServiceAsync extends IClientServiceAsync
     public void prepareExportDataSetProteins(TableExportCriteria<TableModelRowWithObject<DataSetProtein>> exportCriteria,
             AsyncCallback<String> callback);
 
-    /** @see IPhosphoNetXClientService#listSamplesWithAbundanceByProtein(ListSampleAbundanceByProteinCriteria) */
-    public void listSamplesWithAbundanceByProtein(ListSampleAbundanceByProteinCriteria criteria,
-            AsyncCallback<ResultSet<SampleWithPropertiesAndAbundance>> callback);
+    /** @see IPhosphoNetXClientService#listProteinRelatedSamplesByProtein(ListSampleAbundanceByProteinCriteria) */
+    public void listProteinRelatedSamplesByProtein(ListSampleAbundanceByProteinCriteria criteria,
+            AsyncCallback<TypedTableResultSet<ProteinRelatedSample>> callback);
 
-    /** @see IPhosphoNetXClientService#prepareExportSamplesWithAbundance(TableExportCriteria) */
-    public void prepareExportSamplesWithAbundance(
-            TableExportCriteria<SampleWithPropertiesAndAbundance> exportCriteria,
+    /** @see IPhosphoNetXClientService#prepareExportProteinRelatedSamples(TableExportCriteria) */
+    public void prepareExportProteinRelatedSamples(
+            TableExportCriteria<TableModelRowWithObject<ProteinRelatedSample>> exportCriteria,
             AsyncCallback<String> callback);
 
     /** @see IPhosphoNetXClientService#listRawDataSamples(IResultSetConfig) */
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinRelatedSampleGrid.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinRelatedSampleGrid.java
new file mode 100644
index 0000000000000000000000000000000000000000..57e737198dee783a5eed6af461db44ead2bd338e
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinRelatedSampleGrid.java
@@ -0,0 +1,115 @@
+/*
+ * 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.plugin.phosphonetx.client.web.client.application;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
+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.framework.DisplayTypeIDGenerator;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.TypedTableGrid;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IDisposableComponent;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TypedTableResultSet;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.IPhosphoNetXClientServiceAsync;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListSampleAbundanceByProteinCriteria;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ProteinRelatedSampleGridColumnIDs;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinRelatedSample;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
+
+/**
+ * A {@link LayoutContainer} which contains the grid where {@link SampleWithPropertiesAndAbundance}s
+ * of specified Protein are displayed.
+ * 
+ * @author Piotr Buczek
+ */
+public class ProteinRelatedSampleGrid extends TypedTableGrid<ProteinRelatedSample>
+{
+    private static final String PREFIX = GenericConstants.ID_PREFIX + "protein_related_sample_grid";
+
+    // browser consists of the grid and additional toolbars (paging, filtering)
+    public static final String BROWSER_ID = PREFIX + "_main";
+
+    public static final String GRID_ID = PREFIX + TypedTableGrid.GRID_POSTFIX;
+
+    public static final String EDIT_BUTTON_ID = BROWSER_ID + "_edit-button";
+
+    public static final String SHOW_DETAILS_BUTTON_ID = BROWSER_ID + "_show-details-button";
+
+    private final IViewContext<IPhosphoNetXClientServiceAsync> phosphoViewContext;
+
+    public static IDisposableComponent createGridForProteinSamples(
+            final IViewContext<IPhosphoNetXClientServiceAsync> viewContext,
+            final TechId proteinReferenceID, Long experimentIDOrNull, final String gridId)
+    {
+        final ListSampleAbundanceByProteinCriteria criteria =
+                new ListSampleAbundanceByProteinCriteria();
+        criteria.setProteinReferenceID(proteinReferenceID);
+        criteria.setExperimentID(experimentIDOrNull);
+        final ProteinRelatedSampleGrid browserGrid =
+                new ProteinRelatedSampleGrid(viewContext, criteria, gridId);
+        return browserGrid.asDisposableWithoutToolbar();
+    }
+
+    private ListSampleAbundanceByProteinCriteria criteria;
+
+    private ProteinRelatedSampleGrid(
+            final IViewContext<IPhosphoNetXClientServiceAsync> viewContext,
+            ListSampleAbundanceByProteinCriteria criteria, String gridId)
+    {
+        super(viewContext.getCommonViewContext(), gridId, true,
+                DisplayTypeIDGenerator.SAMPLE_DETAILS_GRID);
+        this.phosphoViewContext = viewContext;
+        setId(BROWSER_ID);
+        this.criteria = criteria;
+    }
+
+    @Override
+    protected void listTableRows(
+            DefaultResultSetConfig<String, TableModelRowWithObject<ProteinRelatedSample>> resultSetConfig,
+            AsyncCallback<TypedTableResultSet<ProteinRelatedSample>> callback)
+    {
+        criteria.copyPagingConfig(resultSetConfig);
+        phosphoViewContext.getService().listProteinRelatedSamplesByProtein(criteria, callback);
+    }
+    
+    
+
+    @Override
+    protected List<String> getColumnIdsOfFilters()
+    {
+        return Arrays.asList(ProteinRelatedSampleGridColumnIDs.SAMPLE_IDENTIFIER,
+                ProteinRelatedSampleGridColumnIDs.ABUNDANCE);
+    }
+
+    @Override
+    protected void prepareExportEntities(
+            TableExportCriteria<TableModelRowWithObject<ProteinRelatedSample>> exportCriteria,
+            AbstractAsyncCallback<String> callback)
+    {
+        phosphoViewContext.getService().prepareExportProteinRelatedSamples(exportCriteria, callback);
+    }
+
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinSamplesSection.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinSamplesSection.java
index c7e2459e6648b82f18cc3ea442a4b671db9a2ad7..5e77754c4e4bcd59f7563a5d3234b388efd86ce2 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinSamplesSection.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinSamplesSection.java
@@ -51,7 +51,7 @@ public class ProteinSamplesSection extends ContentPanel
         setBodyBorder(true);
         setLayout(new FitLayout());
         Long experimentID = experimentOrNull == null ? null : experimentOrNull.getId();
-        disposableComponent = SampleAbundanceBrowserGrid.createGridForProteinSamples(viewContext,
+        disposableComponent = ProteinRelatedSampleGrid.createGridForProteinSamples(viewContext,
                 proteinReferenceID, experimentID, createGridId(proteinReferenceID));
         add(disposableComponent.getComponent());
     }
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/SampleAbundanceBrowserGrid.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/SampleAbundanceBrowserGrid.java
deleted file mode 100644
index 103df9e2aee84f13a78a27ce7cc6ebfd96266dfa..0000000000000000000000000000000000000000
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/SampleAbundanceBrowserGrid.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * 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.plugin.phosphonetx.client.web.client.application;
-
-import java.util.List;
-import java.util.Set;
-
-import com.extjs.gxt.ui.client.widget.Dialog;
-import com.extjs.gxt.ui.client.widget.LayoutContainer;
-import com.extjs.gxt.ui.client.widget.button.Button;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-
-import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
-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.framework.DisplayTypeIDGenerator;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.BaseEntityModel;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.RealNumberRenderer;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.AbstractEntityBrowserGrid;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.ColumnDefsAndConfigs;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IBrowserGridActionInvoker;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IDisposableComponent;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.entity.PropertyTypesCriteria;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.entity.PropertyTypesCriteriaProvider;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.AbstractDataListDeletionConfirmationDialog;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.IDataRefreshCallback;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSet;
-import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TableExportCriteria;
-import ch.systemsx.cisd.openbis.generic.shared.basic.GridRowModel;
-import ch.systemsx.cisd.openbis.generic.shared.basic.IColumnDefinition;
-import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.IPhosphoNetXClientServiceAsync;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.application.columns.SampleAbundanceColDefKind;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.application.model.SampleAbundanceModelFactory;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListSampleAbundanceByProteinCriteria;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
-
-/**
- * A {@link LayoutContainer} which contains the grid where {@link SampleWithPropertiesAndAbundance}s
- * of specified Protein are displayed.
- * 
- * @author Piotr Buczek
- */
-public class SampleAbundanceBrowserGrid
-        extends
-        AbstractEntityBrowserGrid<SampleWithPropertiesAndAbundance, BaseEntityModel<SampleWithPropertiesAndAbundance>, ListSampleAbundanceByProteinCriteria>
-{
-    private static final String PREFIX = GenericConstants.ID_PREFIX + "sample_abundance-browser";
-
-    // browser consists of the grid and additional toolbars (paging, filtering)
-    public static final String BROWSER_ID = PREFIX + "_main";
-
-    public static final String GRID_ID = PREFIX + "_grid";
-
-    public static final String EDIT_BUTTON_ID = BROWSER_ID + "_edit-button";
-
-    public static final String SHOW_DETAILS_BUTTON_ID = BROWSER_ID + "_show-details-button";
-
-    private final IViewContext<IPhosphoNetXClientServiceAsync> phosphoViewContext;
-
-    public static IDisposableComponent createGridForProteinSamples(
-            final IViewContext<IPhosphoNetXClientServiceAsync> viewContext,
-            final TechId proteinReferenceID, Long experimentIDOrNull, final String gridId)
-    {
-        final ListSampleAbundanceByProteinCriteria criteria =
-                new ListSampleAbundanceByProteinCriteria();
-        criteria.setProteinReferenceID(proteinReferenceID);
-        criteria.setExperimentID(experimentIDOrNull);
-
-        ISampleAbundanceCriteriaProvider criteriaProvider =
-                new SampleAbundanceCriteriaProvider(viewContext, criteria);
-        // we do not refresh the grid, the criteria provider will do this when property types will
-        // be loaded
-        boolean refreshAutomatically = false;
-        final SampleAbundanceBrowserGrid browserGrid =
-                new SampleAbundanceBrowserGrid(viewContext, criteriaProvider, gridId,
-                        refreshAutomatically);
-        browserGrid.updateCriteriaProviderAndRefresh();
-        browserGrid.extendBottomToolbar();
-        return browserGrid.asDisposableWithoutToolbar();
-    }
-
-    public static interface ISampleAbundanceCriteriaProvider extends
-            ICriteriaProvider<ListSampleAbundanceByProteinCriteria>, IPropertyTypesProvider
-    {
-    }
-
-    public static interface IPropertyTypesProvider
-    {
-        public List<PropertyType> tryGetPropertyTypes();
-    }
-
-    /**
-     * Besides providing the static {@link ListSampleAbundanceByProteinCriteria} this class provides
-     * all property types which should be used to build the grid property columns. It is also able
-     * to refresh these properties from the server.
-     */
-    private static class SampleAbundanceCriteriaProvider implements
-            ISampleAbundanceCriteriaProvider
-    {
-        private final ICriteriaProvider<PropertyTypesCriteria> propertyTypeProvider;
-
-        private final ListSampleAbundanceByProteinCriteria criteria;
-
-        public SampleAbundanceCriteriaProvider(IViewContext<?> viewContext,
-                ListSampleAbundanceByProteinCriteria criteria)
-        {
-            this.propertyTypeProvider =
-                    new PropertyTypesCriteriaProvider(viewContext, EntityKind.SAMPLE);
-            this.criteria = criteria;
-        }
-
-        public List<PropertyType> tryGetPropertyTypes()
-        {
-            PropertyTypesCriteria propertyTypesCriteria = propertyTypeProvider.tryGetCriteria();
-            if (propertyTypesCriteria != null)
-            {
-                return propertyTypesCriteria.tryGetPropertyTypes();
-            } else
-            {
-                return null;
-            }
-        }
-
-        public ListSampleAbundanceByProteinCriteria tryGetCriteria()
-        {
-            return criteria;
-        }
-
-        public void update(Set<DatabaseModificationKind> observedModifications,
-                IDataRefreshCallback dataRefreshCallback)
-        {
-            propertyTypeProvider.update(observedModifications, dataRefreshCallback);
-        }
-
-        public DatabaseModificationKind[] getRelevantModifications()
-        {
-            return propertyTypeProvider.getRelevantModifications();
-        }
-
-    }
-
-    // property types used in the previous refresh operation or null if it has not occurred yet
-    private final List<PropertyType> previousPropertyTypes;
-
-    // provides property types which will be used to build property columns in the grid and
-    // criteria to filter samples
-    private final ISampleAbundanceCriteriaProvider propertyTypesAndCriteriaProvider;
-
-    private SampleAbundanceBrowserGrid(
-            final IViewContext<IPhosphoNetXClientServiceAsync> viewContext,
-            ISampleAbundanceCriteriaProvider criteriaProvider, String gridId,
-            boolean refreshAutomatically)
-    {
-        super(viewContext.getCommonViewContext(), gridId, refreshAutomatically,
-                DisplayTypeIDGenerator.SAMPLE_DETAILS_GRID);
-        this.phosphoViewContext = viewContext;
-        this.propertyTypesAndCriteriaProvider = criteriaProvider;
-        this.previousPropertyTypes = null;
-        setId(BROWSER_ID);
-    }
-
-    @Override
-    protected ICriteriaProvider<ListSampleAbundanceByProteinCriteria> getCriteriaProvider()
-    {
-        return propertyTypesAndCriteriaProvider;
-    }
-
-    // adds show, show-details and invalidate buttons
-    private void extendBottomToolbar()
-    {
-        addEntityOperationsLabel();
-
-        String showDetailsTitle = viewContext.getMessage(Dict.BUTTON_SHOW_DETAILS);
-        Button showDetailsButton =
-                createSelectedItemButton(showDetailsTitle, asShowEntityInvoker(false));
-        showDetailsButton.setId(SHOW_DETAILS_BUTTON_ID);
-        addButton(showDetailsButton);
-
-        String editTitle = viewContext.getMessage(Dict.BUTTON_EDIT);
-        Button editButton = createSelectedItemButton(editTitle, asShowEntityInvoker(true));
-        editButton.setId(EDIT_BUTTON_ID);
-        addButton(editButton);
-
-        addButton(createSelectedItemsButton(viewContext.getMessage(Dict.BUTTON_DELETE),
-                new AbstractCreateDialogListener()
-                    {
-                        @Override
-                        protected Dialog createDialog(
-                                List<SampleWithPropertiesAndAbundance> samples,
-                                IBrowserGridActionInvoker invoker)
-                        {
-                            return new SampleListDeletionConfirmationDialog(viewContext, samples,
-                                    createRefreshCallback(invoker));
-                        }
-                    }));
-        allowMultipleSelection(); // we allow deletion of multiple samples
-
-        addEntityOperationsSeparator();
-    }
-
-    private final static class SampleListDeletionConfirmationDialog extends
-            AbstractDataListDeletionConfirmationDialog<SampleWithPropertiesAndAbundance>
-    {
-
-        private final IViewContext<ICommonClientServiceAsync> viewContext;
-
-        public SampleListDeletionConfirmationDialog(
-                IViewContext<ICommonClientServiceAsync> viewContext,
-                List<SampleWithPropertiesAndAbundance> data, AbstractAsyncCallback<Void> callback)
-        {
-            super(viewContext, data, callback);
-            this.viewContext = viewContext;
-        }
-
-        @Override
-        protected void executeDeletion(AsyncCallback<Void> deletionCallback)
-        {
-            viewContext.getCommonService().deleteSamples(TechId.createList(data),
-                    reason.getValue(), deletionCallback);
-        }
-
-        @Override
-        protected String getEntityName()
-        {
-            return EntityKind.SAMPLE.getDescription();
-        }
-
-    }
-
-    @Override
-    protected EntityType tryToGetEntityType()
-    {
-        return null;
-    }
-
-    @Override
-    protected void listEntities(
-            DefaultResultSetConfig<String, SampleWithPropertiesAndAbundance> resultSetConfig,
-            AbstractAsyncCallback<ResultSet<SampleWithPropertiesAndAbundance>> callback)
-    {
-        criteria.copyPagingConfig(resultSetConfig);
-        phosphoViewContext.getService().listSamplesWithAbundanceByProtein(criteria, callback);
-    }
-
-    @Override
-    protected BaseEntityModel<SampleWithPropertiesAndAbundance> createModel(
-            GridRowModel<SampleWithPropertiesAndAbundance> entity)
-    {
-        return SampleAbundanceModelFactory.createModel(viewContext, entity, viewContext
-                .getDisplaySettingsManager().getRealNumberFormatingParameters());
-    }
-
-    @Override
-    protected List<IColumnDefinition<SampleWithPropertiesAndAbundance>> getInitialFilters()
-    {
-        return asColumnFilters(new SampleAbundanceColDefKind[]
-            { SampleAbundanceColDefKind.CODE, SampleAbundanceColDefKind.SAMPLE_IDENTIFIER,
-                    SampleAbundanceColDefKind.ABUNDANCE });
-    }
-
-    @Override
-    protected void showEntityViewer(SampleWithPropertiesAndAbundance sample, boolean editMode,
-            boolean active)
-    {
-        showEntityInformationHolderViewer(sample, editMode, active);
-    }
-
-    @Override
-    protected void prepareExportEntities(
-            TableExportCriteria<SampleWithPropertiesAndAbundance> exportCriteria,
-            AbstractAsyncCallback<String> callback)
-    {
-        phosphoViewContext.getService().prepareExportSamplesWithAbundance(exportCriteria, callback);
-    }
-
-    @Override
-    protected ColumnDefsAndConfigs<SampleWithPropertiesAndAbundance> createColumnsDefinition()
-    {
-        assert criteria != null : "criteria not set!";
-        List<PropertyType> propertyTypes = propertyTypesAndCriteriaProvider.tryGetPropertyTypes();
-        assert propertyTypes != null : "propertyTypes not set!";
-
-        ColumnDefsAndConfigs<SampleWithPropertiesAndAbundance> schema =
-                SampleAbundanceModelFactory.createColumnsSchema(viewContext, propertyTypes);
-        schema.setGridCellRendererFor(SampleAbundanceColDefKind.CODE.id(),
-                createInternalLinkCellRenderer());
-        schema.setGridCellRendererFor(SampleAbundanceColDefKind.ABUNDANCE.id(),
-                new RealNumberRenderer(viewContext.getDisplaySettingsManager()
-                        .getRealNumberFormatingParameters()));
-        return schema;
-    }
-
-    @Override
-    protected boolean hasColumnsDefinitionChanged(ListSampleAbundanceByProteinCriteria newCriteria)
-    {
-        List<PropertyType> newPropertyTypes =
-                propertyTypesAndCriteriaProvider.tryGetPropertyTypes();
-        if (newPropertyTypes == null)
-        {
-            return false; // we are before the first auto-refresh
-        }
-        if (previousPropertyTypes == null)
-        {
-            return true; // first refresh
-        }
-        if (previousPropertyTypes.equals(newPropertyTypes) == false)
-        {
-            return true;
-        }
-        EntityType newEntityType = null;
-        EntityType prevEntityType = null;
-        return hasColumnsDefinitionChanged(newEntityType, prevEntityType);
-    }
-
-    @Override
-    protected Set<DatabaseModificationKind> getGridRelevantModifications()
-    {
-        Set<DatabaseModificationKind> result = getGridRelevantModifications(ObjectKind.SAMPLE);
-        // TODO 2009-07-31, Piotr Buczek: can abundance change?
-        return result;
-    }
-
-    @Override
-    protected IColumnDefinitionKind<SampleWithPropertiesAndAbundance>[] getStaticColumnsDefinition()
-    {
-        return SampleAbundanceColDefKind.values();
-    }
-
-    @Override
-    protected EntityKind getEntityKind()
-    {
-        return EntityKind.SAMPLE;
-    }
-
-}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/columns/SampleAbundanceColDefKind.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/columns/SampleAbundanceColDefKind.java
deleted file mode 100644
index 21ba9883473c66eb6d25b239b51b4a4572b308e2..0000000000000000000000000000000000000000
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/columns/SampleAbundanceColDefKind.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.plugin.phosphonetx.client.web.client.application.columns;
-
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.AbstractColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionKind;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
-
-public enum SampleAbundanceColDefKind implements
-        IColumnDefinitionKind<SampleWithPropertiesAndAbundance>
-{
-    CODE(new AbstractColumnDefinitionKind<SampleWithPropertiesAndAbundance>(Dict.CODE)
-        {
-            @Override
-            public String tryGetValue(SampleWithPropertiesAndAbundance entity)
-            {
-                return entity.getCode();
-            }
-        }),
-
-    SAMPLE_IDENTIFIER(new AbstractColumnDefinitionKind<SampleWithPropertiesAndAbundance>(
-            Dict.SAMPLE_IDENTIFIER)
-        {
-            @Override
-            public String tryGetValue(SampleWithPropertiesAndAbundance entity)
-            {
-                return entity.getIdentifier();
-            }
-        }),
-
-    SAMPLE_TYPE(new AbstractColumnDefinitionKind<SampleWithPropertiesAndAbundance>(
-            Dict.SAMPLE_TYPE, 150)
-        {
-            @Override
-            public String tryGetValue(SampleWithPropertiesAndAbundance entity)
-            {
-                return entity.getSampleType().getCode();
-            }
-        }),
-
-    ABUNDANCE(
-            new AbstractColumnDefinitionKind<SampleWithPropertiesAndAbundance>(
-                    ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.application.Dict.ABUNDANCE,
-                    100, false, true)
-                {
-                    @Override
-                    public String tryGetValue(SampleWithPropertiesAndAbundance entity)
-                    {
-                        return Double.toString(entity.getAbundance());
-                    }
-                });
-
-    private final AbstractColumnDefinitionKind<SampleWithPropertiesAndAbundance> columnDefinitionKind;
-
-    private SampleAbundanceColDefKind(
-            AbstractColumnDefinitionKind<SampleWithPropertiesAndAbundance> columnDefinitionKind)
-    {
-        this.columnDefinitionKind = columnDefinitionKind;
-    }
-
-    public String id()
-    {
-        return name();
-    }
-
-    public AbstractColumnDefinitionKind<SampleWithPropertiesAndAbundance> getDescriptor()
-    {
-        return columnDefinitionKind;
-    }
-
-}
\ No newline at end of file
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/model/SampleAbundanceModelFactory.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/model/SampleAbundanceModelFactory.java
deleted file mode 100644
index 5021fef01891a32ecdfdd0dd1ccbf43955c6c9ae..0000000000000000000000000000000000000000
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/model/SampleAbundanceModelFactory.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.plugin.phosphonetx.client.web.client.application.model;
-
-import java.util.List;
-
-import com.extjs.gxt.ui.client.data.ModelData;
-
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.BaseEntityModel;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.model.EntityGridModelFactory;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.columns.framework.IColumnDefinitionUI;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.ColumnDefsAndConfigs;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider;
-import ch.systemsx.cisd.openbis.generic.shared.basic.GridRowModel;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.RealNumberFormatingParameters;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.application.columns.SampleAbundanceColDefKind;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
-
-/**
- * {@link ModelData} for {@link SampleWithPropertiesAndAbundance}. Allows to display static columns
- * and properties.
- * 
- * @author Pitor Buczek
- */
-public final class SampleAbundanceModelFactory
-{
-    public static ColumnDefsAndConfigs<SampleWithPropertiesAndAbundance> createColumnsSchema(
-            final IViewContext<?> viewContext, List<PropertyType> propertyTypes)
-    {
-        return new SampleAbundanceModelFactory(viewContext).doCreateColumnsSchema(viewContext,
-                propertyTypes);
-    }
-
-    public static BaseEntityModel<SampleWithPropertiesAndAbundance> createModel(
-            final IViewContext<?> viewContext,
-            GridRowModel<SampleWithPropertiesAndAbundance> entity,
-            RealNumberFormatingParameters realNumberFormatingParameters)
-    {
-        List<IColumnDefinitionUI<SampleWithPropertiesAndAbundance>> allColumnsDefinition =
-                new SampleAbundanceModelFactory(viewContext).createColumnsSchemaForRendering(
-                        entity, realNumberFormatingParameters);
-        BaseEntityModel<SampleWithPropertiesAndAbundance> model =
-                new BaseEntityModel<SampleWithPropertiesAndAbundance>(entity, allColumnsDefinition);
-        return model;
-    }
-
-    private final EntityGridModelFactory<SampleWithPropertiesAndAbundance> entityGridModelFactory;
-
-    private SampleAbundanceModelFactory(final IViewContext<?> viewContext)
-    {
-        this.entityGridModelFactory =
-                new EntityGridModelFactory<SampleWithPropertiesAndAbundance>(viewContext,
-                        SampleAbundanceColDefKind.values());
-    }
-
-    private List<IColumnDefinitionUI<SampleWithPropertiesAndAbundance>> createColumnsSchemaForRendering(
-            GridRowModel<SampleWithPropertiesAndAbundance> sample,
-            RealNumberFormatingParameters realNumberFormatingParameters)
-    {
-        List<IColumnDefinitionUI<SampleWithPropertiesAndAbundance>> columns =
-                entityGridModelFactory.createColumnsSchemaForRendering(sample,
-                        realNumberFormatingParameters);
-        return columns;
-    }
-
-    private ColumnDefsAndConfigs<SampleWithPropertiesAndAbundance> doCreateColumnsSchema(
-            IMessageProvider messageProvider, List<PropertyType> propertyTypes)
-    {
-        assert messageProvider != null : "message provider needed to create table headers";
-
-        ColumnDefsAndConfigs<SampleWithPropertiesAndAbundance> columns =
-                entityGridModelFactory.createColumnsSchema(messageProvider, propertyTypes);
-        return columns;
-    }
-}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/dto/ListSampleAbundanceByProteinCriteria.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/dto/ListSampleAbundanceByProteinCriteria.java
index 9cf36395a4abae89bebf929704acb87030199b89..4bed88dfb40ddbcf4ee40f17050e349d497b3d75 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/dto/ListSampleAbundanceByProteinCriteria.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/dto/ListSampleAbundanceByProteinCriteria.java
@@ -20,7 +20,8 @@ import com.google.gwt.user.client.rpc.IsSerializable;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DefaultResultSetConfig;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelRowWithObject;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinRelatedSample;
 
 /**
  * 
@@ -28,7 +29,7 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPr
  * @author Franz-Josef Elmer
  */
 public class ListSampleAbundanceByProteinCriteria extends
-        DefaultResultSetConfig<String, SampleWithPropertiesAndAbundance> implements IsSerializable
+        DefaultResultSetConfig<String, TableModelRowWithObject<ProteinRelatedSample>> implements IsSerializable
 {
     private TechId experimentID;
     private TechId proteinReferenceID;
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/dto/ProteinRelatedSampleGridColumnIDs.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/dto/ProteinRelatedSampleGridColumnIDs.java
new file mode 100644
index 0000000000000000000000000000000000000000..534169c087cfebd006328055e68c629b0df6075b
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/dto/ProteinRelatedSampleGridColumnIDs.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011 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.plugin.phosphonetx.client.web.client.dto;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class ProteinRelatedSampleGridColumnIDs
+{
+    public static final String SAMPLE_IDENTIFIER = "SAMPLE_IDENTIFIER";
+    public static final String SAMPLE_TYPE = "SAMPLE_TYPE";
+    public static final String ABUNDANCE = "ABUNDANCE";
+    public static final String MODIFICATION_POSITION = "MODIFICATION_POSITION";
+    public static final String MODIFICATION_MASS = "MODIFICATION_MASS";
+    public static final String MODIFICATION_FRACTION = "MODIFICATION_FRACTION";
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/public/phosphonetx-dictionary.js b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/public/phosphonetx-dictionary.js
index 9d11d62ada5b1480a18ce6b93e48313368aa090f..6ad7c0c9744efa590cb5796e1f11134ef79db8ee 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/public/phosphonetx-dictionary.js
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/public/phosphonetx-dictionary.js
@@ -38,8 +38,13 @@ var phosphonetx = {
   false_discovery_rate_column: "FDR (Protein Prophet)",
   protein_probability: "Probability (Protein Prophet)",
   
-  // SampleAbudndance Browser
-  abundance: "Abundance",
+  // ProteinRelatedSampleGrid
+  openbis_protein_related_sample_grid_main_SAMPLE_IDENTIFIER: "Identifier",
+  openbis_protein_related_sample_grid_main_SAMPLE_TYPE: "Sample Type",
+  openbis_protein_related_sample_grid_main_ABUNDANCE: "Abundance",
+  openbis_protein_related_sample_grid_main_MODIFICATION_POSITION: "Modification Position",
+  openbis_protein_related_sample_grid_main_MODIFICATION_MASS: "Modification Mass",
+  openbis_protein_related_sample_grid_main_MODIFICATION_FRACTION: "Modification Fraction",
   
   // MS_INJECTION annotation wizard
   
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/ListSampleAbundanceDataProvider.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/ListSampleAbundanceDataProvider.java
deleted file mode 100644
index 1889d5494559711a4e0b924551d4473ae65889d4..0000000000000000000000000000000000000000
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/ListSampleAbundanceDataProvider.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2009 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.plugin.phosphonetx.client.web.server;
-
-import java.util.List;
-
-import ch.systemsx.cisd.common.exceptions.UserFailureException;
-import ch.systemsx.cisd.openbis.generic.client.web.server.AbstractOriginalDataProviderWithoutHeaders;
-import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.IPhosphoNetXServer;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
-
-/**
- * 
- *
- * @author Franz-Josef Elmer
- */
-class ListSampleAbundanceDataProvider extends AbstractOriginalDataProviderWithoutHeaders<SampleWithPropertiesAndAbundance>
-{
-    private final IPhosphoNetXServer server;
-
-    private final String sessionToken;
-
-    private final TechId experimentID;
-    
-    private final TechId proteinReferenceID;
-
-    ListSampleAbundanceDataProvider(IPhosphoNetXServer server, String sessionToken,
-            TechId experimentID, TechId proteinReferenceID)
-    {
-        this.server = server;
-        this.sessionToken = sessionToken;
-        this.experimentID = experimentID;
-        this.proteinReferenceID = proteinReferenceID;
-    }
-
-
-    @Override
-    public List<SampleWithPropertiesAndAbundance> getFullOriginalData() throws UserFailureException
-    {
-        return server.listSamplesWithAbundanceByProtein(sessionToken, experimentID, proteinReferenceID);
-    }
-
-}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/PhosphoNetXClientService.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/PhosphoNetXClientService.java
index f569b8264b1fc90355b7a938347f0ccf5e0d4291..f251466367f6e574200e8178daf5035e9b0a1d9c 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/PhosphoNetXClientService.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/PhosphoNetXClientService.java
@@ -76,6 +76,7 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ListSam
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.server.resultset.BiologicalSampleProvider;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.server.resultset.DataSetProteinProvider;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.server.resultset.ParentlessMsInjectionSampleProvider;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.server.resultset.ProteinRelatedSampleProvider;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.server.resultset.ProteinSequenceProvider;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.server.resultset.ProteinSummaryProvider;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.CacheData;
@@ -87,9 +88,9 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.AggregateFun
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.DataSetProtein;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinByExperiment;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinInfo;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinRelatedSample;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSequence;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
 
 /**
  * @author Franz-Josef Elmer
@@ -336,16 +337,19 @@ public class PhosphoNetXClientService extends AbstractClientService implements
         return prepareExportEntities(exportCriteria);
     }
 
-    public ResultSet<SampleWithPropertiesAndAbundance> listSamplesWithAbundanceByProtein(
+    public TypedTableResultSet<ProteinRelatedSample> listProteinRelatedSamplesByProtein(
             ListSampleAbundanceByProteinCriteria criteria)
     {
         final String sessionToken = getSessionToken();
-        return listEntities(criteria, new ListSampleAbundanceDataProvider(server, sessionToken,
-                criteria.getExperimentID(), criteria.getProteinReferenceID()));
+        ProteinRelatedSampleProvider provider =
+                new ProteinRelatedSampleProvider(server, sessionToken, criteria.getExperimentID(),
+                        criteria.getProteinReferenceID());
+        return listEntities(provider, criteria);
     }
 
-    public String prepareExportSamplesWithAbundance(
-            TableExportCriteria<SampleWithPropertiesAndAbundance> exportCriteria)
+    public String prepareExportProteinRelatedSamples(
+            TableExportCriteria<TableModelRowWithObject<ProteinRelatedSample>> exportCriteria)
+            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
     {
         return prepareExportEntities(exportCriteria);
     }
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/resultset/ProteinRelatedSampleProvider.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/resultset/ProteinRelatedSampleProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..645de2ebbe9845fbc22fb61f9a2f56c809e45ee9
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/server/resultset/ProteinRelatedSampleProvider.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2011 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.plugin.phosphonetx.client.web.server.resultset;
+
+import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode.INTEGER;
+import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode.REAL;
+import static ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ProteinRelatedSampleGridColumnIDs.ABUNDANCE;
+import static ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ProteinRelatedSampleGridColumnIDs.MODIFICATION_FRACTION;
+import static ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ProteinRelatedSampleGridColumnIDs.MODIFICATION_MASS;
+import static ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ProteinRelatedSampleGridColumnIDs.MODIFICATION_POSITION;
+import static ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ProteinRelatedSampleGridColumnIDs.SAMPLE_IDENTIFIER;
+import static ch.systemsx.cisd.openbis.plugin.phosphonetx.client.web.client.dto.ProteinRelatedSampleGridColumnIDs.SAMPLE_TYPE;
+
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.client.web.server.resultset.AbstractTableModelProvider;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TypedTableModel;
+import ch.systemsx.cisd.openbis.generic.shared.util.TypedTableModelBuilder;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.IPhosphoNetXServer;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinRelatedSample;
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class ProteinRelatedSampleProvider extends AbstractTableModelProvider<ProteinRelatedSample>
+{
+    private final IPhosphoNetXServer server;
+
+    private final String sessionToken;
+
+    private final TechId experimentID;
+    
+    private final TechId proteinReferenceID;
+
+    public ProteinRelatedSampleProvider(IPhosphoNetXServer server, String sessionToken,
+            TechId experimentID, TechId proteinReferenceID)
+    {
+        this.server = server;
+        this.sessionToken = sessionToken;
+        this.experimentID = experimentID;
+        this.proteinReferenceID = proteinReferenceID;
+    }
+
+    @Override
+    protected TypedTableModel<ProteinRelatedSample> createTableModel()
+    {
+        List<ProteinRelatedSample> samples =
+                server.listProteinRelatedSamplesByProtein(sessionToken, experimentID,
+                        proteinReferenceID);
+        TypedTableModelBuilder<ProteinRelatedSample> builder =
+                new TypedTableModelBuilder<ProteinRelatedSample>();
+        builder.column(SAMPLE_IDENTIFIER);
+        builder.column(SAMPLE_TYPE);
+        builder.column(ABUNDANCE).withDataType(REAL).withDefaultWidth(100);
+        builder.column(MODIFICATION_POSITION).withDataType(INTEGER).withDefaultWidth(100);
+        builder.column(MODIFICATION_MASS).withDataType(REAL).withDefaultWidth(100);
+        builder.column(MODIFICATION_FRACTION).withDataType(REAL).withDefaultWidth(100);
+        for (ProteinRelatedSample sample : samples)
+        {
+            builder.addRow(sample);
+            builder.column(SAMPLE_IDENTIFIER).addString(sample.getIdentifier());
+            builder.column(SAMPLE_TYPE).addString(sample.getEntityType().getCode());
+            builder.column(ABUNDANCE).addDouble(sample.getAbundance());
+            builder.column(MODIFICATION_POSITION).addInteger(sample.getModificationPosition());
+            builder.column(MODIFICATION_MASS).addDouble(sample.getModificationMass());
+            builder.column(MODIFICATION_FRACTION).addDouble(sample.getModificationFraction());
+        }
+        return builder.getModel();
+    }
+
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServer.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServer.java
index 0f66400367bc5130ccafed46a1ad06a15cc9ebe8..c17a9dcb60fd8b9d92b21d5957a6ad963ef0305f 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServer.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServer.java
@@ -16,7 +16,11 @@
 
 package ch.systemsx.cisd.openbis.plugin.phosphonetx.server;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 
 import javax.annotation.Resource;
 
@@ -35,10 +39,14 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IVocabularyDAO;
 import ch.systemsx.cisd.openbis.generic.server.plugin.IDataSetTypeSlaveServerPlugin;
 import ch.systemsx.cisd.openbis.generic.server.plugin.ISampleTypeSlaveServerPlugin;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Vocabulary;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.PropertyTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE;
+import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTypeTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.VocabularyTranslator;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.AccessionNumberBuilder;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.IAbundanceColumnDefinitionTable;
@@ -49,7 +57,7 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.IProteinInfoT
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.IProteinSequenceTable;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.IProteinSummaryTable;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.ISampleProvider;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.ISampleTable;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.SampleIDProvider;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.dataaccess.IPhosphoNetXDAOFactory;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.dataaccess.IProteinQueryDAO;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.IPhosphoNetXServer;
@@ -57,12 +65,18 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.ResourceNames;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.AbundanceColumnDefinition;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.AggregateFunction;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.DataSetProtein;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.Occurrence;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.OccurrenceUtil;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinByExperiment;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinDetails;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinInfo;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinRelatedSample;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSequence;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.AbstractSample;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReference;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.SampleAbundance;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.SamplePeptideModification;
 
 /**
  * @author Franz-Josef Elmer
@@ -207,14 +221,141 @@ public class PhosphoNetXServer extends AbstractServer<IPhosphoNetXServer> implem
         return dataSetProteinTable.getDataSetProteins();
     }
 
-    public List<SampleWithPropertiesAndAbundance> listSamplesWithAbundanceByProtein(
+    public List<ProteinRelatedSample> listProteinRelatedSamplesByProtein(
             String sessionToken, TechId experimentID, TechId proteinReferenceID)
             throws UserFailureException
     {
         final Session session = getSession(sessionToken);
-        ISampleTable sampleTable = specificBOFactory.createSampleTable(session);
-        sampleTable.loadSamplesWithAbundance(experimentID, proteinReferenceID);
-        return sampleTable.getSamples();
+        
+        IProteinDetailsBO proteinDetailsBO = specificBOFactory.createProteinDetailsBO(session);
+        proteinDetailsBO.loadByExperimentAndReference(experimentID, proteinReferenceID);
+        ProteinDetails detailsOrNull = proteinDetailsBO.getDetailsOrNull();
+        String sequenceOrNull = detailsOrNull == null ? null : detailsOrNull.getSequence();
+        IProteinQueryDAO proteinQueryDAO = specificDAOFactory.getProteinQueryDAO();
+        proteinQueryDAO.listProteinSequencesByProteinReference(proteinReferenceID.getId());
+        IDAOFactory daoFactory = getDAOFactory();
+        String experimentPermID =
+                daoFactory.getExperimentDAO().getByTechId(experimentID).getPermId();
+        Map<String, List<SampleAbundance>> sampleAbundanceMap =
+                createSampleMap(proteinQueryDAO.listSampleAbundanceByProtein(experimentPermID,
+                        proteinReferenceID.getId()));
+        Map<String, List<SamplePeptideModification>> samplePeptideModificationMap =
+                createSampleMap(proteinQueryDAO.listSamplePeptideModificatioByProtein(
+                        experimentPermID, proteinReferenceID.getId()));
+        List<ProteinRelatedSample> result = new ArrayList<ProteinRelatedSample>();
+        SampleIDProvider sampleIDProvider = new SampleIDProvider(daoFactory.getSampleDAO());
+        Map<PropertyTypePE, PropertyType> cache = new HashMap<PropertyTypePE, PropertyType>();
+        for (Entry<String, List<SampleAbundance>> entry : sampleAbundanceMap.entrySet())
+        {
+            String key = entry.getKey();
+            SamplePE sample = sampleIDProvider.getSampleOrParentSample(key);
+            List<SampleAbundance> sampleAbundances = entry.getValue();
+            List<SamplePeptideModification> samplePeptideModifications =
+                    samplePeptideModificationMap.get(key);
+            if (samplePeptideModifications == null)
+            {
+                for (SampleAbundance sampleAbundance : sampleAbundances)
+                {
+                    ProteinRelatedSample s = createFrom(sample, cache);
+                    s.setAbundance(sampleAbundance.getAbundance());
+                    result.add(s);
+                }
+            } else
+            {
+                for (SampleAbundance sampleAbundance : sampleAbundances)
+                {
+                    Double abundance = sampleAbundance.getAbundance();
+                    result.addAll(createSamplesForPeptideModifications(samplePeptideModifications,
+                            sample, abundance, sequenceOrNull, cache));
+                }
+            }
+        }
+        for (Entry<String, List<SamplePeptideModification>> entry : samplePeptideModificationMap
+                .entrySet())
+        {
+            String key = entry.getKey();
+            if (sampleAbundanceMap.containsKey(key) == false)
+            {
+                SamplePE sample = sampleIDProvider.getSampleOrParentSample(key);
+                List<SamplePeptideModification> samplePeptideModifications = entry.getValue();
+                result.addAll(createSamplesForPeptideModifications(samplePeptideModifications,
+                        sample, null, sequenceOrNull, cache));
+            }
+        }
+        return result;
+    }
+
+    private List<ProteinRelatedSample> createSamplesForPeptideModifications(
+            List<SamplePeptideModification> samplePeptideModifications, SamplePE sample,
+            Double abundanceOrNull, String sequenceOrNull, Map<PropertyTypePE, PropertyType> cache)
+    {
+        List<ProteinRelatedSample> samples = new ArrayList<ProteinRelatedSample>();
+        for (SamplePeptideModification samplePeptideModification : samplePeptideModifications)
+        {
+            int position = samplePeptideModification.getPosition();
+            if (sequenceOrNull != null)
+            {
+                List<Occurrence> occurances =
+                        OccurrenceUtil.findAllOccurrences(sequenceOrNull,
+                                samplePeptideModification.getSequence());
+                for (Occurrence occurrence : occurances)
+                {
+                    samples.add(createProteinRelatedSample(samplePeptideModification, sample,
+                            abundanceOrNull, position + occurrence.getEndIndex(), cache));
+                }
+            } else
+            {
+                samples.add(createProteinRelatedSample(samplePeptideModification, sample,
+                        abundanceOrNull, position, cache));
+            }
+        }
+        return samples;
+    }
+
+    private ProteinRelatedSample createProteinRelatedSample(
+            SamplePeptideModification samplePeptideModification, SamplePE sample,
+            Double abundanceOrNull, int position, Map<PropertyTypePE, PropertyType> cache)
+    {
+        ProteinRelatedSample s = createFrom(sample, cache);
+        s.setAbundance(abundanceOrNull);
+        s.setModificationFraction(samplePeptideModification.getFraction());
+        s.setModificationMass(samplePeptideModification.getMass());
+        s.setModificationPosition((long) position);
+        return s;
+    }
+    
+    private ProteinRelatedSample createFrom(SamplePE sample, Map<PropertyTypePE, PropertyType> cache)
+    {
+        ProteinRelatedSample s = new ProteinRelatedSample();
+        s.setCode(sample.getCode());
+        s.setEntityType(SampleTypeTranslator.translate(sample.getSampleType(), cache));
+        s.setId(sample.getId());
+        s.setIdentifier(sample.getIdentifier());
+        s.setPermId(sample.getPermId());
+        return s;
+    }
+
+    private <T extends AbstractSample> Map<String, List<T>> createSampleMap(DataSet<T> items)
+    {
+        Map<String, List<T>> map = new HashMap<String, List<T>>();
+        try
+        {
+            for (T item : items)
+            {
+                String samplePermID = item.getSamplePermID();
+                List<T> list = map.get(samplePermID);
+                if (list == null)
+                {
+                    list = new ArrayList<T>();
+                    map.put(samplePermID, list);
+                }
+                list.add(item);
+            }
+        } finally
+        {
+            items.close();
+        }
+        return map;
     }
 
     private String getExperimentPermIDFor(TechId experimentId)
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServerLogger.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServerLogger.java
index 53486a8cc67ef2fb346b7bb72ab1f905f50940f7..4c5181bd993bedd924e3f4416e4f4f97fa0c0e85 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServerLogger.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServerLogger.java
@@ -31,9 +31,9 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.AggregateFun
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.DataSetProtein;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinByExperiment;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinInfo;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinRelatedSample;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSequence;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
 
 /**
  * @author Franz-Josef Elmer
@@ -105,11 +105,10 @@ public class PhosphoNetXServerLogger extends AbstractServerLogger implements IPh
         return null;
     }
 
-    public List<SampleWithPropertiesAndAbundance> listSamplesWithAbundanceByProtein(
-            String sessionToken, TechId experimentID, TechId proteinReferenceID)
-            throws UserFailureException
+    public List<ProteinRelatedSample> listProteinRelatedSamplesByProtein(String sessionToken,
+            TechId experimentID, TechId proteinReferenceID) throws UserFailureException
     {
-        logAccess(sessionToken, "list_samples_with_abundance_by_protein",
+        logAccess(sessionToken, "list_protein_related_samples_by_protein",
                 "EXPERIMENT_ID(%s) PROTEIN_REFERENCE_ID(%s)", experimentID, proteinReferenceID);
         return null;
     }
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/SampleIDProvider.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/SampleIDProvider.java
index 2659c03c86c754330df357daec930d791ea661fb..c953a8020afc7619a3badb11a806177138b55c43 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/SampleIDProvider.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/business/SampleIDProvider.java
@@ -29,12 +29,12 @@ import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
  *
  * @author Franz-Josef Elmer
  */
-class SampleIDProvider implements ISampleIDProvider
+public class SampleIDProvider implements ISampleIDProvider
 {
     private final ISampleDAO sampleDAO;
     private final Map<String, SamplePE> samples = new LinkedHashMap<String, SamplePE>();
 
-    SampleIDProvider(ISampleDAO sampleDAO)
+    public SampleIDProvider(ISampleDAO sampleDAO)
     {
         this.sampleDAO = sampleDAO;
     }
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/dataaccess/IProteinQueryDAO.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/dataaccess/IProteinQueryDAO.java
index 0bbed1dc0b756ac020d9360fe8c9274595a8eadc..ca31be88e7ee7a2dc84cfdfdfe38141c92555ea5 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/dataaccess/IProteinQueryDAO.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/dataaccess/IProteinQueryDAO.java
@@ -32,6 +32,7 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReference;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReferenceWithProbabilityAndPeptide;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.ProteinReferenceWithProtein;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.SampleAbundance;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.SamplePeptideModification;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.dto.Sequence;
 
 /**
@@ -120,4 +121,18 @@ public interface IProteinQueryDAO extends BaseQuery
     public DataSet<SampleAbundance> listSampleAbundanceByProtein(String experimentPermID,
             long proteinReferenceID);
     
+    @Select("select distinct mf.id, samples.perm_id, fraction, pos, mass, sequence "
+            + "from modification_fractions as mf left join modifications as m on mf.modi_id = m.id "
+            + "                     left join modified_peptides as mp on m.mope_id = mp.id "
+            + "                     left join peptides as pe on mp.pept_id = pe.id "
+            + "                     left join proteins as p on pe.prot_id = p.id "
+            + "                     left join data_sets as d on p.dase_id = d.id "
+            + "                     left join experiments as e on d.expe_id = e.id "
+            + "                     left join identified_proteins as ip on ip.prot_id = p.id "
+            + "                     left join sequences as s on ip.sequ_id = s.id "
+            + "                     left join samples on mf.samp_id = samples.id "
+            + "where e.perm_id = ?{1} and s.prre_id = ?{2} and ip.is_primary = 't'")
+    public DataSet<SamplePeptideModification> listSamplePeptideModificatioByProtein(
+            String experimentPermID, long proteinReferenceID);
+    
 }
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/IPhosphoNetXServer.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/IPhosphoNetXServer.java
index 1b276854f9313d78e270ba75543055a620cd386e..f493f51f9c8aa7dbcfefc92386b8cc3a219189f7 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/IPhosphoNetXServer.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/IPhosphoNetXServer.java
@@ -33,9 +33,9 @@ import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.AggregateFun
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.DataSetProtein;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinByExperiment;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinInfo;
+import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinRelatedSample;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSequence;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.ProteinSummary;
-import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.basic.dto.SampleWithPropertiesAndAbundance;
 
 /**
  * 
@@ -91,8 +91,7 @@ public interface IPhosphoNetXServer extends IServer
     
     @Transactional
     @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
-    public List<SampleWithPropertiesAndAbundance> listSamplesWithAbundanceByProtein(
+    public List<ProteinRelatedSample> listProteinRelatedSamplesByProtein(
             String sessionToken, TechId experimentID, TechId proteinReferenceID)
             throws UserFailureException;
-
 }
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/OccurrenceUtil.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/OccurrenceUtil.java
index 0e9815b776963a88e6df2a390db3261066c0362e..8fee021d248b447ef15ae3eb6690e995b2cd19d5 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/OccurrenceUtil.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/OccurrenceUtil.java
@@ -66,17 +66,25 @@ public class OccurrenceUtil
         List<Occurrence> result = new ArrayList<Occurrence>();
         for (String word : peptides)
         {
-            int startIndex = 0;
-            while (true)
+            result.addAll(findAllOccurrences(protein, word));
+        }
+        Collections.sort(result);
+        return result;
+    }
+    
+    public static List<Occurrence> findAllOccurrences(String protein, String peptide)
+    {
+        List<Occurrence> result = new ArrayList<Occurrence>();
+        int startIndex = 0;
+        while (true)
+        {
+            int occurrenceIndex = protein.indexOf(peptide, startIndex);
+            if (occurrenceIndex == -1)
             {
-                int occurrenceIndex = protein.indexOf(word, startIndex);
-                if (occurrenceIndex == -1)
-                {
-                    break;
-                }
-                result.add(new Occurrence(word, occurrenceIndex));
-                startIndex = occurrenceIndex + 1; // maybe the word overlaps with itself?
+                break;
             }
+            result.add(new Occurrence(peptide, occurrenceIndex));
+            startIndex = occurrenceIndex + 1; // maybe the word overlaps with itself?
         }
         Collections.sort(result);
         return result;
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/ProteinRelatedSample.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/ProteinRelatedSample.java
new file mode 100644
index 0000000000000000000000000000000000000000..c7b03185ffa720b497606cd30dada11a62d82a68
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/basic/dto/ProteinRelatedSample.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2011 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.plugin.phosphonetx.shared.basic.dto;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWithPermId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.ISerializable;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.BasicEntityType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ServiceVersionHolder;
+
+/**
+ * Sample related to a protein. Contains information about abundance and amino-acid modification.
+ *
+ * @author Franz-Josef Elmer
+ */
+public class ProteinRelatedSample implements ISerializable, IEntityInformationHolderWithPermId
+{
+    private static final long serialVersionUID = ServiceVersionHolder.VERSION;
+    
+    private Long id;
+    
+    private String permId;
+    
+    private String code;
+    
+    private String identifier;
+    
+    private BasicEntityType entityType;
+    
+    private Double abundance;
+    
+    private Long modificationPosition;
+    
+    private Double modificationMass;
+    
+    private Double modificationFraction;
+
+    public Long getId()
+    {
+        return id;
+    }
+
+    public void setId(Long id)
+    {
+        this.id = id;
+    }
+
+    public String getPermId()
+    {
+        return permId;
+    }
+
+    public void setPermId(String permId)
+    {
+        this.permId = permId;
+    }
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    public void setCode(String code)
+    {
+        this.code = code;
+    }
+
+    public BasicEntityType getEntityType()
+    {
+        return entityType;
+    }
+
+    public void setEntityType(BasicEntityType entityType)
+    {
+        this.entityType = entityType;
+    }
+
+    public String getIdentifier()
+    {
+        return identifier;
+    }
+
+    public void setIdentifier(String identifier)
+    {
+        this.identifier = identifier;
+    }
+
+    public Double getAbundance()
+    {
+        return abundance;
+    }
+
+    public void setAbundance(Double abundance)
+    {
+        this.abundance = abundance;
+    }
+
+    public Long getModificationPosition()
+    {
+        return modificationPosition;
+    }
+
+    public void setModificationPosition(Long modificationPosition)
+    {
+        this.modificationPosition = modificationPosition;
+    }
+
+    public Double getModificationMass()
+    {
+        return modificationMass;
+    }
+
+    public void setModificationMass(Double modificationMass)
+    {
+        this.modificationMass = modificationMass;
+    }
+
+    public Double getModificationFraction()
+    {
+        return modificationFraction;
+    }
+
+    public void setModificationFraction(Double modificationFraction)
+    {
+        this.modificationFraction = modificationFraction;
+    }
+
+    public EntityKind getEntityKind()
+    {
+        return EntityKind.SAMPLE;
+    }
+
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/AbstractSample.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/AbstractSample.java
new file mode 100644
index 0000000000000000000000000000000000000000..326612ad249e7294528dc602e59eff7fb56d6f46
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/AbstractSample.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2011 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.plugin.phosphonetx.shared.dto;
+
+import net.lemnik.eodsql.ResultColumn;
+
+
+/**
+ * Abstract super class of sample.
+ *
+ * @author Franz-Josef Elmer
+ */
+public abstract class AbstractSample extends AbstractDTOWithID
+{
+    private static final long serialVersionUID = 1L;
+    
+    @ResultColumn("perm_id")
+    private String samplePermID;
+
+    public final String getSamplePermID()
+    {
+        return samplePermID;
+    }
+    
+    public final void setSamplePermID(String samplePermID)
+    {
+        this.samplePermID = samplePermID;
+    }
+    
+
+}
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/SampleAbundance.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/SampleAbundance.java
index b1d72f816cb3256f48ccd644ec608348d66f51e6..95ad92ec160aa7cbf5b057fbd75d67397b0cdeb8 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/SampleAbundance.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/SampleAbundance.java
@@ -24,13 +24,10 @@ import net.lemnik.eodsql.ResultColumn;
  *
  * @author Franz-Josef Elmer
  */
-public class SampleAbundance extends AbstractDTOWithID
+public class SampleAbundance extends AbstractSample
 {
     private static final long serialVersionUID = 1L;
 
-    @ResultColumn("perm_id")
-    private String samplePermID;
-
     @ResultColumn("value")
     private double abundance;
     
@@ -44,14 +41,4 @@ public class SampleAbundance extends AbstractDTOWithID
         this.abundance = abundance;
     }
 
-    public final String getSamplePermID()
-    {
-        return samplePermID;
-    }
-    
-    public final void setSamplePermID(String samplePermID)
-    {
-        this.samplePermID = samplePermID;
-    }
-    
 }
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/SamplePeptideModification.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/SamplePeptideModification.java
new file mode 100644
index 0000000000000000000000000000000000000000..facf90d4536afbcada6428644e7396d2a7453521
--- /dev/null
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/shared/dto/SamplePeptideModification.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2011 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.plugin.phosphonetx.shared.dto;
+
+import net.lemnik.eodsql.ResultColumn;
+
+
+/**
+ * 
+ *
+ * @author Franz-Josef Elmer
+ */
+public class SamplePeptideModification extends AbstractSample
+{
+    private static final long serialVersionUID = 1L;
+
+    @ResultColumn("fraction")
+    private double fraction;
+    
+    @ResultColumn("pos")
+    private int position;
+    
+    @ResultColumn("mass")
+    private double mass;
+    
+    @ResultColumn("sequence")
+    private String sequence;
+
+    public double getFraction()
+    {
+        return fraction;
+    }
+
+    public void setFraction(double fraction)
+    {
+        this.fraction = fraction;
+    }
+
+    public int getPosition()
+    {
+        return position;
+    }
+
+    public void setPosition(int position)
+    {
+        this.position = position;
+    }
+
+    public double getMass()
+    {
+        return mass;
+    }
+
+    public void setMass(double mass)
+    {
+        this.mass = mass;
+    }
+
+    public String getSequence()
+    {
+        return sequence;
+    }
+
+    public void setSequence(String sequence)
+    {
+        this.sequence = sequence;
+    }
+
+}