diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java
index a727294bb59388b1aadcbf97e93ac1f2ce9dbbcd..4c111c7392ef212e17857339dd6df7dda7d37ad5 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java
@@ -192,6 +192,8 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends BaseEntityMod
 
     protected final ICellListener<T> showEntityViewerLinkClickListener;
 
+    protected final TableModificationsManager tableModificationsManager;
+
     // ------ private section. NOTE: it should remain unaccessible to subclasses! ---------------
 
     private static final int PAGE_SIZE = Constants.GRID_PAGE_SIZE;
@@ -217,9 +219,6 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends BaseEntityMod
 
     private final ToolBar modificationsToolbar;
 
-    @SuppressWarnings("unused")
-    private final TableModificationsManager tableModificationsManager;
-
     private final IDisplayTypeIDGenerator displayTypeIDGenerator;
 
     // --------- private non-final fields
@@ -277,7 +276,8 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends BaseEntityMod
         this.filterToolbar =
                 new FilterToolbar<T>(viewContext, gridId, this, createApplyFiltersDelagator());
         this.tableModificationsManager = new TableModificationsManager();
-        this.modificationsToolbar = new ModificationsToolbar(viewContext, asActionInvoker());
+        this.modificationsToolbar =
+                new ModificationsToolbar(viewContext, tableModificationsManager);
 
         this.contentPanel = createEmptyContentPanel();
         bottomToolbars = createBottomToolbars(contentPanel, pagingToolbar);
@@ -967,19 +967,6 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends BaseEntityMod
                     }
                 }
 
-                public void saveModifications()
-                {
-                    finishedModifications = 0;
-                    for (Entry<M, List<IModification>> entry : modificationsByModel.entrySet())
-                    {
-                        applyModifications(entry.getKey(), entry.getValue());
-                    }
-                }
-
-                public void cancelModifications()
-                {
-                    clearModifications();
-                }
             };
     }
 
@@ -1788,7 +1775,8 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends BaseEntityMod
                     } else
                     {
                         showModificationsBar();
-                        handleEditingEvent(model, columnID, StringUtils.toStringOrNull(value));
+                        tableModificationsManager.handleEditingEvent(model, columnID,
+                                StringUtils.toStringOrNull(value));
                     }
                 }
             });
@@ -1945,6 +1933,25 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends BaseEntityMod
     // Table Modifications
     //
 
+    /**
+     * Apply specified modifications to the model. Should be overriden by subclasses. Default
+     * implementation does nothing.
+     */
+    protected void applyModifications(M model, List<IModification> modifications)
+    {
+
+    }
+
+    /** Manager of table modifications */
+    public interface ITableModificationsManager
+    {
+        /** save all modifications made in the table to the DB and refresh the table */
+        void saveModifications();
+
+        /** cancel all modifications made in the table and refresh the table */
+        void cancelModifications();
+    }
+
     public interface IModification
     {
         String getColumnID();
@@ -1976,158 +1983,130 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends BaseEntityMod
         }
     }
 
-    private static class TableModificationsManager
+    protected class TableModificationsManager implements ITableModificationsManager
     {
+        private final Map<M, List<IModification>> modificationsByModel =
+                new LinkedHashMap<M, List<IModification>>();
 
-    }
-
-    // TODO 2011-08-06, Piotr Buczek: refactor the code - move to TableModificationsManager
-
-    private final Map<M, String> failedModifications = new HashMap<M, String>();
+        private final Map<M, String> failedModifications = new HashMap<M, String>();
 
-    private int finishedModifications = 0;
+        private int finishedModifications = 0;
 
-    private final Map<M, List<IModification>> modificationsByModel =
-            new LinkedHashMap<M, List<IModification>>();
-
-    private void clearModifications()
-    {
-        finishedModifications = 0;
-        failedModifications.clear();
-        modificationsByModel.clear();
-        hideModificationsBar();
-        refresh();
-    }
+        //
+        // ITableModificationsManager
+        //
 
-    /** Handle cell editing event. */
-    private void handleEditingEvent(M model, String columnID, String newValueOrNull)
-    {
-        List<IModification> modificationsForModel = modificationsByModel.get(model);
-        if (modificationsForModel == null)
+        public void saveModifications()
         {
-            modificationsForModel = new ArrayList<IModification>();
-            modificationsByModel.put(model, modificationsForModel);
+            finishedModifications = 0;
+            for (Entry<M, List<IModification>> entry : modificationsByModel.entrySet())
+            {
+                applyModifications(entry.getKey(), entry.getValue());
+            }
         }
-        modificationsForModel.add(new Modification(columnID, newValueOrNull));
-    }
 
-    /**
-     * Apply specified modification to the model. Should be overriden by subclasses. Default
-     * implementation does nothing.
-     */
-    protected void applyModifications(M model, List<IModification> modifications)
-    {
+        public void cancelModifications()
+        {
+            clearModifications();
+        }
 
-    }
+        //
 
-    protected AsyncCallback<EntityPropertyUpdatesResult> createApplyModificationsCallback(
-            final M model, final List<IModification> modifications)
-    {
-        return new AbstractAsyncCallback<EntityPropertyUpdatesResult>(viewContext)
-            {
-                @Override
-                protected void process(EntityPropertyUpdatesResult result)
+        /** @return callback for given modifications made to specified model. */
+        protected AsyncCallback<EntityPropertyUpdatesResult> createApplyModificationsCallback(
+                final M model, final List<IModification> modifications)
+        {
+            return new AbstractAsyncCallback<EntityPropertyUpdatesResult>(viewContext)
                 {
-                    finishedModifications++;
-                    String errorMessage = result.tryGetErrorMessage();
-                    if (errorMessage != null)
+                    @Override
+                    protected void process(EntityPropertyUpdatesResult result)
                     {
-                        handleError(errorMessage);
+                        finishedModifications++;
+                        String errorMessage = result.tryGetErrorMessage();
+                        if (errorMessage != null)
+                        {
+                            handleError(errorMessage);
+                        }
+                        if (isApplyModificationsComplete())
+                        {
+                            onApplyModificationsComplete();
+                        }
                     }
-                    if (isApplyModificationsComplete())
+
+                    @Override
+                    public void finishOnFailure(Throwable caught)
                     {
-                        onApplyModificationsComplete();
+                        finishedModifications++;
+                        handleError(caught.getMessage());
+                        if (isApplyModificationsComplete())
+                        {
+                            onApplyModificationsComplete();
+                        }
                     }
-                }
 
-                @Override
-                public void finishOnFailure(Throwable caught)
-                {
-                    finishedModifications++;
-                    handleError(caught.getMessage());
-                    if (isApplyModificationsComplete())
+                    private void handleError(String errorMessage)
                     {
-                        onApplyModificationsComplete();
+                        failedModifications.put(model, errorMessage);
                     }
-                }
-
-                private void handleError(String errorMessage)
-                {
-                    failedModifications.put(model, errorMessage);
-                }
-            };
-    }
-
-    private boolean isApplyModificationsComplete()
-    {
-        return finishedModifications == modificationsByModel.size();
-    }
+                };
+        }
 
-    private void onApplyModificationsComplete()
-    {
-        if (failedModifications.size() > 0)
+        /** Handle cell editing event. */
+        protected void handleEditingEvent(M model, String columnID, String newValueOrNull)
         {
-            String failureTitle =
-                    (failedModifications.size() == modificationsByModel.size()) ? "Operation failed"
-                            : "Operation partly failed";
-            String failureReport = createFailedModificationsReport();
-            MessageBox.alert(failureTitle, failureReport, null);
-            refresh();
-        } else
-        {
-            GWTUtils.displayInfo("All modifications successfully applied.");
-            refresh();
+            List<IModification> modificationsForModel = modificationsByModel.get(model);
+            if (modificationsForModel == null)
+            {
+                modificationsForModel = new ArrayList<IModification>();
+                modificationsByModel.put(model, modificationsForModel);
+            }
+            modificationsForModel.add(new Modification(columnID, newValueOrNull));
         }
-        clearModifications();
-    }
 
-    private String createFailedModificationsReport()
-    {
-        assert failedModifications.size() > 0;
-        StringBuilder result = new StringBuilder();
-        result.append("Modifications of " + failedModifications.size() + " entities failed:");
-        for (String error : failedModifications.values())
+        private boolean isApplyModificationsComplete()
         {
-            result.append("<br/>- " + error);
+            return finishedModifications == modificationsByModel.size();
         }
-        return result.toString();
-    }
 
-    /**
-     * Creates a callback object which invokes {@link #refresh()} after server-side editing action
-     * took place.
-     */
-    protected AsyncCallback<Void> createPostEditingRefreshCallback()
-    {
-        return createPostEditingCallback(new IDelegatedAction()
+        private void onApplyModificationsComplete()
+        {
+            if (failedModifications.size() > 0)
             {
-                public void execute()
-                {
-                    asActionInvoker().refresh();
-                }
-            });
-    }
+                String failureTitle =
+                        (failedModifications.size() == modificationsByModel.size()) ? "Operation failed"
+                                : "Operation partly failed";
+                String failureReport = createFailedModificationsReport();
+                MessageBox.alert(failureTitle, failureReport, null);
+                refresh();
+            } else
+            {
+                GWTUtils.displayInfo("All modifications successfully applied.");
+                refresh();
+            }
+            clearModifications();
+        }
 
-    /**
-     * Creates a callback object which invokes specified refresh action after server-side editing
-     * action took place.
-     */
-    protected AsyncCallback<Void> createPostEditingCallback(final IDelegatedAction refreshAction)
-    {
-        return new AbstractAsyncCallback<Void>(viewContext)
+        private String createFailedModificationsReport()
+        {
+            assert failedModifications.size() > 0;
+            StringBuilder result = new StringBuilder();
+            result.append("Modifications of " + failedModifications.size() + " entities failed:");
+            for (String error : failedModifications.values())
             {
-                @Override
-                protected void process(Void result)
-                {
-                    refreshAction.execute();
-                }
+                result.append("<br/>- " + error);
+            }
+            return result.toString();
+        }
+
+        private void clearModifications()
+        {
+            finishedModifications = 0;
+            failedModifications.clear();
+            modificationsByModel.clear();
+            hideModificationsBar();
+            refresh();
+        }
 
-                @Override
-                public void finishOnFailure(Throwable caught)
-                {
-                    refreshAction.execute();
-                }
-            };
     }
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractEntityBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractEntityBrowserGrid.java
index 5ab38705fdbff8b906d674b8297ed6319bc9f447..0216cb840686a3fe1fb3ea3166416e05259d81f3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractEntityBrowserGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractEntityBrowserGrid.java
@@ -159,7 +159,7 @@ public abstract class AbstractEntityBrowserGrid<T extends IEntityPropertiesHolde
             updates.addModifiedProperty(propertyCode, modification.tryGetNewValue());
         }
         viewContext.getService().updateProperties(updates,
-                createApplyModificationsCallback(model, modifications));
+                tableModificationsManager.createApplyModificationsCallback(model, modifications));
     }
 
     /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractEntityGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractEntityGrid.java
index 61f874287dc67c9baef632984582dc7a1f30eb33..e7c23c7426608b962e29f174642c89d912777fe1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractEntityGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractEntityGrid.java
@@ -89,7 +89,7 @@ public abstract class AbstractEntityGrid<E extends IEntityInformationHolderWithP
             updates.addModifiedProperty(propertyCode, modification.tryGetNewValue());
         }
         viewContext.getService().updateProperties(updates,
-                createApplyModificationsCallback(model, modifications));
+                tableModificationsManager.createApplyModificationsCallback(model, modifications));
     }
 
     @Override
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/IBrowserGridActionInvoker.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/IBrowserGridActionInvoker.java
index 4886040b5c7f4674f65fb0685439b294b502b488..77c0809b0a34a01a11212848fe07a2dadc9ab3f3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/IBrowserGridActionInvoker.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/IBrowserGridActionInvoker.java
@@ -1,6 +1,5 @@
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid;
 
-
 /**
  * Interface to delegate export and refresh actions.
  */
@@ -14,7 +13,4 @@ public interface IBrowserGridActionInvoker
 
     void toggleFilters(boolean show);
 
-    void saveModifications();
-
-    void cancelModifications();
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/modifications/ModificationsToolbar.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/modifications/ModificationsToolbar.java
index 9b1379a7da36ba5fa28ae47d6aa7b2e278833012..7ab93b2faf03e01534fd12d64060533a84077013 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/modifications/ModificationsToolbar.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/modifications/ModificationsToolbar.java
@@ -26,8 +26,7 @@ import com.google.gwt.user.client.ui.AbstractImagePrototype;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.IGenericImageBundle;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
-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.AbstractBrowserGrid.ITableModificationsManager;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider;
 
 /**
@@ -40,17 +39,9 @@ public class ModificationsToolbar extends ToolBar
     private static final IGenericImageBundle IMAGE_BUNDLE = GWT
             .<IGenericImageBundle> create(IGenericImageBundle.class);
 
-    private final IMessageProvider messageProvider;
-
-    @SuppressWarnings("unused")
-    private final IViewContext<?> viewContext; // TODO remove if not used
-
-    public ModificationsToolbar(final IViewContext<?> viewContext,
-            final IBrowserGridActionInvoker browserActionInvoker)
+    public ModificationsToolbar(final IMessageProvider messageProvider,
+            final ITableModificationsManager manager)
     {
-        this.viewContext = viewContext;
-        this.messageProvider = viewContext;
-
         add(new Label(messageProvider.getMessage(Dict.TABLE_MODIFICATIONS)));
 
         final AbstractImagePrototype confirmIcon =
@@ -62,7 +53,7 @@ public class ModificationsToolbar extends ToolBar
                 @Override
                 public void componentSelected(ButtonEvent be)
                 {
-                    browserActionInvoker.saveModifications();
+                    manager.saveModifications();
                 }
             }));
         add(new Button("Cancel", cancelIcon, new SelectionListener<ButtonEvent>()
@@ -70,7 +61,7 @@ public class ModificationsToolbar extends ToolBar
                 @Override
                 public void componentSelected(ButtonEvent be)
                 {
-                    browserActionInvoker.cancelModifications();
+                    manager.cancelModifications();
                 }
             }));
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/managed_property/ManagedPropertyGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/managed_property/ManagedPropertyGrid.java
index 03bd6d4b6dda9a929f84b03398c615a5a018cf1c..54a01318146b1a40a11f9e9aa7a6767d432628d1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/managed_property/ManagedPropertyGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/managed_property/ManagedPropertyGrid.java
@@ -227,16 +227,6 @@ public class ManagedPropertyGrid extends TypedTableGrid<ReportRowModel>
                 {
                     delegate.configure();
                 }
-
-                public void saveModifications()
-                {
-                    delegate.saveModifications();
-                }
-
-                public void cancelModifications()
-                {
-                    delegate.cancelModifications();
-                }
             };
     }