diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractCommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractCommonServer.java
index b13229d1551f3093c5fd895a0aa691ee281e137c..eff5902fbc383bd13a9975ee9426a6e3f5ddb7a1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractCommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractCommonServer.java
@@ -33,6 +33,7 @@ import ch.systemsx.cisd.openbis.generic.shared.IServer;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DisplaySettings;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 
 /**
  * @author Franz-Josef Elmer
@@ -46,9 +47,10 @@ abstract class AbstractCommonServer<T extends IServer> extends AbstractServer<T>
 
     public AbstractCommonServer(IAuthenticationService authenticationService,
             ISessionManager<Session> sessionManager, IDAOFactory daoFactory,
+            IPropertiesBatchManager propertiesBatchManager,
             ICommonBusinessObjectFactory businessObjectFactory)
     {
-        super(sessionManager, daoFactory);
+        super(sessionManager, daoFactory, propertiesBatchManager);
         this.authenticationService = authenticationService;
         this.businessObjectFactory = businessObjectFactory;
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java
index 8f0f85f4b0690e6cea86de045df99684e33cf284..bd6dfa4938e4fabfb0199b3e306f4c6c66a9e79e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java
@@ -52,18 +52,20 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GridCustomColumnPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityInformationWithPropertiesHolder;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IAuthSession;
+import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityInformationWithPropertiesHolder;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.RoleAssignmentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SessionContextDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleSession;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 import ch.systemsx.cisd.openbis.generic.shared.translator.GridCustomExpressionTranslator.GridCustomColumnTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
 import ch.systemsx.cisd.openbis.generic.shared.util.ServerUtils;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
+import ch.systemsx.cisd.openbis.plugin.generic.server.PropertiesBatchManager;
 
 /**
  * An <i>abstract</i> {@link IServer} implementation.
@@ -93,6 +95,8 @@ public abstract class AbstractServer<T> extends AbstractServiceWithLogger<T> imp
     @Resource(name = ComponentNames.REMOTE_HOST_VALIDATOR)
     private IRemoteHostValidator remoteHostValidator;
 
+    private IPropertiesBatchManager propertiesBatchManager;
+
     protected AbstractServer()
     {
         operationLog.info(String.format("Creating new '%s' implementation: '%s'.",
@@ -100,23 +104,33 @@ public abstract class AbstractServer<T> extends AbstractServiceWithLogger<T> imp
     }
 
     protected AbstractServer(final ISessionManager<Session> sessionManager,
-            final IDAOFactory daoFactory)
+            final IDAOFactory daoFactory, IPropertiesBatchManager propertiesBatchManager)
     {
         this();
         this.sessionManager = sessionManager;
         this.daoFactory = daoFactory;
+        this.propertiesBatchManager = propertiesBatchManager;
     }
 
     // For testing purpose.
     protected AbstractServer(final ISessionManager<Session> sessionManager,
-            final IDAOFactory daoFactory,
+            final IDAOFactory daoFactory, IPropertiesBatchManager propertiesBatchManager,
             final ISampleTypeSlaveServerPlugin sampleTypeSlaveServerPlugin,
             final IDataSetTypeSlaveServerPlugin dataSetTypeSlaveServerPlugin)
     {
-        this(sessionManager, daoFactory);
+        this(sessionManager, daoFactory, propertiesBatchManager);
         this.sampleTypeSlaveServerPlugin = sampleTypeSlaveServerPlugin;
         this.dataSetTypeSlaveServerPlugin = dataSetTypeSlaveServerPlugin;
     }
+    
+    protected IPropertiesBatchManager getPropertiesBatchManager()
+    {
+        if (propertiesBatchManager == null)
+        {
+            propertiesBatchManager = new PropertiesBatchManager(daoFactory);
+        }
+        return propertiesBatchManager;
+    }
 
     public final void setSampleTypeSlaveServerPlugin(
             ISampleTypeSlaveServerPlugin sampleTypeSlaveServerPlugin)
@@ -432,6 +446,7 @@ public abstract class AbstractServer<T> extends AbstractServiceWithLogger<T> imp
     protected void registerSamples(final Session session,
             final NewSamplesWithTypes newSamplesWithType, PersonPE registratorOrNull)
     {
+        getPropertiesBatchManager().manageProperties(newSamplesWithType);
         final SampleType sampleType = newSamplesWithType.getSampleType();
         final List<NewSample> newSamples = newSamplesWithType.getNewSamples();
         assert sampleType != null : "Unspecified sample type.";
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
index ccbfdf9426eeb578217dafca0674e16d36d5c91a..14618d72957b16b6a25197aae936ea78d86828a3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java
@@ -209,6 +209,7 @@ import ch.systemsx.cisd.openbis.generic.shared.translator.VocabularyTermTranslat
 import ch.systemsx.cisd.openbis.generic.shared.translator.VocabularyTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.util.EntityHelper;
 import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 
 public final class CommonServer extends AbstractCommonServer<ICommonServerForInternalUse> implements
         ICommonServerForInternalUse
@@ -220,10 +221,20 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
             final ICommonBusinessObjectFactory businessObjectFactory,
             final LastModificationState lastModificationState)
     {
-        super(authenticationService, sessionManager, daoFactory, businessObjectFactory);
-        this.lastModificationState = lastModificationState;
+        this(authenticationService, sessionManager, daoFactory, null, businessObjectFactory,
+                lastModificationState);
     }
 
+    CommonServer(final IAuthenticationService authenticationService,
+            final ISessionManager<Session> sessionManager, final IDAOFactory daoFactory,
+            IPropertiesBatchManager propertiesBatchManager,
+            final ICommonBusinessObjectFactory businessObjectFactory,
+            final LastModificationState lastModificationState)
+    {
+        super(authenticationService, sessionManager, daoFactory, propertiesBatchManager, businessObjectFactory);
+        this.lastModificationState = lastModificationState;
+    }
+    
     ICommonBusinessObjectFactory getBusinessObjectFactory()
     {
         return businessObjectFactory;
@@ -1691,7 +1702,21 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         {
             if (etpt.isDynamic() == false)
             {
-                columns.add(etpt.getPropertyType().getCode());
+                String code = etpt.getPropertyType().getCode();
+                if (etpt.isManaged())
+                {
+                    String script = etpt.getScript().getScript();
+                    ManagedPropertyEvaluator evaluator = new ManagedPropertyEvaluator(script);
+                    List<String> batchColumnNames = evaluator.getBatchColumnNames();
+                    Collections.sort(batchColumnNames);
+                    for (String name : batchColumnNames)
+                    {
+                        columns.add(code + ':' + name);
+                    }
+                } else
+                {
+                    columns.add(code);
+                }
             }
         }
     }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
index a5b912956262a6530d7b88214e6140e81173eca8..fbb836599f492501a3f87d6dfedaf223044d58f9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java
@@ -117,6 +117,7 @@ import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTypeTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.VocabularyTermTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 
 /**
  * @author Franz-Josef Elmer
@@ -131,11 +132,19 @@ public class ETLService extends AbstractCommonServer<IETLService> implements IET
             ISessionManager<Session> sessionManager, IDAOFactory daoFactory,
             ICommonBusinessObjectFactory boFactory, IDataStoreServiceFactory dssFactory)
     {
-        super(authenticationService, sessionManager, daoFactory, boFactory);
+        this(authenticationService, sessionManager, daoFactory, null, boFactory, dssFactory);
+    }
+
+    ETLService(IAuthenticationService authenticationService,
+            ISessionManager<Session> sessionManager, IDAOFactory daoFactory,
+            IPropertiesBatchManager propertiesBatchManager,
+            ICommonBusinessObjectFactory boFactory, IDataStoreServiceFactory dssFactory)
+    {
+        super(authenticationService, sessionManager, daoFactory, propertiesBatchManager, boFactory);
         this.daoFactory = daoFactory;
         this.dssFactory = dssFactory;
     }
-
+    
     public IETLService createLogger(IInvocationLoggerContext context)
     {
         return new ETLServiceLogger(getSessionManager(), context);
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServer.java
index b1cd9b867fa5fad6822eeb6d944989157f50d057..1d0cfd79de254ce6ebdfabe820dcfc3e68e9df5e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/TrackingServer.java
@@ -36,6 +36,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TrackingDataSetCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TrackingSampleCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 
 public final class TrackingServer extends AbstractServer<ITrackingServer> implements
         ITrackingServer
@@ -43,12 +44,20 @@ public final class TrackingServer extends AbstractServer<ITrackingServer> implem
     private final ICommonBusinessObjectFactory businessObjectFactory;
 
     public TrackingServer(final ISessionManager<Session> sessionManager,
-            final IDAOFactory daoFactory, final ICommonBusinessObjectFactory businessObjectFactory)
+            final IDAOFactory daoFactory,
+            final ICommonBusinessObjectFactory businessObjectFactory)
     {
-        super(sessionManager, daoFactory);
-        this.businessObjectFactory = businessObjectFactory;
+        this(sessionManager, daoFactory, null, businessObjectFactory);
     }
 
+    TrackingServer(final ISessionManager<Session> sessionManager,
+            final IDAOFactory daoFactory, IPropertiesBatchManager propertiesBatchManager,
+            final ICommonBusinessObjectFactory businessObjectFactory)
+    {
+        super(sessionManager, daoFactory, propertiesBatchManager);
+        this.businessObjectFactory = businessObjectFactory;
+    }
+    
     ICommonBusinessObjectFactory getBusinessObjectFactory()
     {
         return businessObjectFactory;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java
index 494b758616d186566f06984ad017eb570a5df268..62c387ad3580da164a97dcaa2372d809dae70337 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationService.java
@@ -64,6 +64,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SessionContextDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 
 /**
  * @author Franz-Josef Elmer
@@ -81,9 +82,9 @@ public class GeneralInformationService extends AbstractServer<IGeneralInformatio
     }
 
     GeneralInformationService(ISessionManager<Session> sessionManager, IDAOFactory daoFactory,
-            ICommonServer commonServer)
+            IPropertiesBatchManager propertiesBatchManager, ICommonServer commonServer)
     {
-        super(sessionManager, daoFactory);
+        super(sessionManager, daoFactory, propertiesBatchManager);
         this.commonServer = commonServer;
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/BasicConstant.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/BasicConstant.java
index cbc8e53621827c4171b2effcde86f527b0a82b71..0e4e9e01029eec661f3d6919a47b22b4c6890f21 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/BasicConstant.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/BasicConstant.java
@@ -41,7 +41,7 @@ public class BasicConstant
     private static final char UNI_REPLACEMENT_CHAR = 0xFFFD;
 
     /** Prefix of property value that contains error message. */
-    public static final String ERROR_PROPERTY_PREFIX = "" + UNI_REPLACEMENT_CHAR;
+    public static final String ERROR_PROPERTY_PREFIX = Character.toString(UNI_REPLACEMENT_CHAR);
 
     /** Value of dynamic property before it is evaluated. */
     public static final String DYNAMIC_PROPERTY_PLACEHOLDER_VALUE = ERROR_PROPERTY_PREFIX
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/IPropertiesBean.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/IPropertiesBean.java
new file mode 100644
index 0000000000000000000000000000000000000000..8dfb9110404b71c603d06cd950929622f244f039
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/IPropertiesBean.java
@@ -0,0 +1,30 @@
+/*
+ * 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.generic.shared.basic.dto;
+
+
+/**
+ * Interface implemented by beans with properties attribute.
+ *
+ * @author Franz-Josef Elmer
+ */
+public interface IPropertiesBean
+{
+    public IEntityProperty[] getProperties();
+    
+    public void setProperties(IEntityProperty[] properties);
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/NewSample.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/NewSample.java
index 9168598c8028fc33e8281d8d33cf1ae508e5cd33..ee95ab2649c273873522e7fbc40761863d0ca9b3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/NewSample.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/NewSample.java
@@ -25,7 +25,7 @@ import ch.systemsx.cisd.common.annotation.BeanProperty;
  * 
  * @author Christian Ribeaud
  */
-public class NewSample extends Identifier<NewSample> implements Comparable<NewSample>
+public class NewSample extends Identifier<NewSample> implements Comparable<NewSample>, IPropertiesBean
 {
     private static final long serialVersionUID = ServiceVersionHolder.VERSION;
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/api/ValidationException.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/api/ValidationException.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ecd9701cc6fa431dbd8e3e96d0c223eb3418e74
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/api/ValidationException.java
@@ -0,0 +1,40 @@
+/*
+ * 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.generic.shared.basic.dto.api;
+
+import ch.systemsx.cisd.common.exceptions.UserFailureException;
+
+/**
+ * Exception thrown by jython scripts in case of invalid input.
+ *
+ * @author Franz-Josef Elmer
+ */
+public class ValidationException extends UserFailureException
+{
+    private static final long serialVersionUID = 1L;
+
+    public ValidationException(String message)
+    {
+        super(message);
+    }
+
+    public ValidationException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/ManagedPropertyEvaluator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/ManagedPropertyEvaluator.java
index 300a7b9ba6dd456e736d4da8f5a77b88af241b39..a0c60f175cbbf899985d20283eb60ba90e2a7267 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/ManagedPropertyEvaluator.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/ManagedPropertyEvaluator.java
@@ -16,42 +16,57 @@
 
 package ch.systemsx.cisd.openbis.generic.shared.managed_property;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.log4j.Logger;
 
 import ch.systemsx.cisd.common.evaluator.Evaluator;
+import ch.systemsx.cisd.common.evaluator.EvaluatorException;
 import ch.systemsx.cisd.common.logging.LogCategory;
 import ch.systemsx.cisd.common.logging.LogFactory;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ManagedProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.IManagedProperty;
-import ch.systemsx.cisd.openbis.generic.shared.managed_property.api.ISimpleTableModelBuilderAdaptor;
+import ch.systemsx.cisd.openbis.generic.shared.managed_property.api.ScriptUtilityFactory;
 
 /**
  * Class for evaluating scripts that control managed properties.
  * 
  * @author Chandrasekhar Ramakrishnan
  */
-// TODO 2011-01-14, Piotr Buczek: it should be possible to reuse evaluator by set of properties
 public class ManagedPropertyEvaluator
 {
     private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION,
             ManagedPropertyEvaluator.class);
 
-    private final String scriptExpression;
-
     /**
      * The name of the script that expects the property to be there and updates ui configuration.
      */
-    private static final String CONFIGURE_UI_EXPRESSION = "configureUI()";
+    private static final String CONFIGURE_UI_EXPRESSION = "configureUI";
 
     /**
      * The name of the script that expects the property to be there and updates the value.
      */
-    private static final String UPDATE_VALUE_EXPRESSION = "updateValue()";
+    private static final String UPDATE_VALUE_EXPRESSION = "updateValue";
 
+    /**
+     * The name of the function that returns an array of column names.
+     */
+    private static final String BATCH_COLUMN_NAMES_FUNCTION = "batchColumnNames";
+    
+    /**
+     * The name of the function that expects a map of bindings.
+     */
+    private static final String UPDATE_FROM_BATCH_INPUT_FUNCTION = "updateFromBatchInput";
+    
     private static final String PROPERTY_VARIABLE_NAME = "property";
+    
+    private final Evaluator evaluator;
 
     public ManagedPropertyEvaluator(String scriptExpression)
     {
-        this.scriptExpression = scriptExpression;
+        evaluator = new Evaluator("", ScriptUtilityFactory.class, scriptExpression);
     }
 
     public void evalConfigureProperty(IManagedProperty managedProperty)
@@ -62,10 +77,8 @@ public class ManagedPropertyEvaluator
                     managedProperty));
         }
 
-        Evaluator evaluator =
-                new Evaluator(CONFIGURE_UI_EXPRESSION, ScriptUtilityFactory.class, scriptExpression);
         evaluator.set(PROPERTY_VARIABLE_NAME, managedProperty);
-        evaluator.eval();
+        evaluator.evalFunction(CONFIGURE_UI_EXPRESSION);
     }
 
     public void evaluateUpdateProperty(IManagedProperty managedProperty)
@@ -76,25 +89,34 @@ public class ManagedPropertyEvaluator
                     managedProperty));
         }
 
-        Evaluator evaluator =
-                new Evaluator(UPDATE_VALUE_EXPRESSION, ScriptUtilityFactory.class, scriptExpression);
         evaluator.set(PROPERTY_VARIABLE_NAME, managedProperty);
-        evaluator.eval();
+        evaluator.evalFunction(UPDATE_VALUE_EXPRESSION);
     }
-
-    //
-    // utlilities
-    //
-
-    /**
-     * This utility class should shouldn't expose anything outside of Managed Property API. No
-     * method should return or take as an argument anything outside of the API.
-     */
-    public static class ScriptUtilityFactory
+    
+    public List<String> getBatchColumnNames()
     {
-        public static ISimpleTableModelBuilderAdaptor createTableBuilder()
+        Object result = evaluator.evalFunction(BATCH_COLUMN_NAMES_FUNCTION);
+        if (result instanceof List == false)
+        {
+            throw new EvaluatorException("Function '" + BATCH_COLUMN_NAMES_FUNCTION
+                    + "' doesn't return a List but an object of type '"
+                    + result.getClass().getName() + "': " + result);
+        }
+        List<?> list = (List<?>) result;
+        ArrayList<String> columnNames = new ArrayList<String>();
+        for (Object element : list)
         {
-            return SimpleTableModelBuilderAdaptor.create();
+            columnNames.add(element.toString());
         }
+        return columnNames;
     }
+
+    public String updateFromBatchInput(Map<String, String> bindings)
+    {
+        ManagedProperty property = new ManagedProperty();
+        evaluator.set(PROPERTY_VARIABLE_NAME, property);
+        evaluator.evalFunction(UPDATE_FROM_BATCH_INPUT_FUNCTION, bindings);
+        return property.getValue();
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/api/ScriptUtilityFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/api/ScriptUtilityFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..90a7f94ca8d218d2578f52b0a2df91122356f5f7
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/managed_property/api/ScriptUtilityFactory.java
@@ -0,0 +1,30 @@
+package ch.systemsx.cisd.openbis.generic.shared.managed_property.api;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.ValidationException;
+import ch.systemsx.cisd.openbis.generic.shared.managed_property.SimpleTableModelBuilderAdaptor;
+
+/**
+ * This utility class with function to be used by jython scripts for managed properties.
+ * <p>
+ * All methods of this class are part of the Managed Properties API.
+ */
+public class ScriptUtilityFactory
+{
+    /**
+     * Creates a table builder.
+     */
+    public static ISimpleTableModelBuilderAdaptor createTableBuilder()
+    {
+        return SimpleTableModelBuilderAdaptor.create();
+    }
+    
+    /**
+     * Creates a {@link ValidationException} with specified message. 
+     */
+    // Violates Java naming conventions for method because it should look like a constructor
+    // for invocations in jython. 
+    public static ValidationException ValidationException(String message)
+    {
+        return new ValidationException(message);
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServer.java
index f1b69d6e9a54fbc6fd3d2893ebb2b3d954c2fd89..c8412ff0fea785b6c03d961a9140f640ace9dc04 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServer.java
@@ -42,6 +42,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTranslator;
 import ch.systemsx.cisd.openbis.plugin.demo.shared.IDemoServer;
 import ch.systemsx.cisd.openbis.plugin.demo.shared.ResourceNames;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 
 /**
  * The concrete {@link IDemoServer} implementation.
@@ -60,11 +61,13 @@ public final class DemoServer extends AbstractServer<IDemoServer> implements IDe
 
     @Private
     DemoServer(final ISessionManager<Session> sessionManager, final IDAOFactory daoFactory,
+            IPropertiesBatchManager propertiesBatchManager,
             final IDemoBusinessObjectFactory businessObjectFactory,
             final ISampleTypeSlaveServerPlugin sampleTypeSlaveServerPlugin,
             final IDataSetTypeSlaveServerPlugin dataSetTypeSlaveServerPlugin)
     {
-        super(sessionManager, daoFactory, sampleTypeSlaveServerPlugin, dataSetTypeSlaveServerPlugin);
+        super(sessionManager, daoFactory, propertiesBatchManager, sampleTypeSlaveServerPlugin,
+                dataSetTypeSlaveServerPlugin);
         this.businessObjectFactory = businessObjectFactory;
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
index 084ced56627a528b59730bd1d8f3099beb2d8c09..def1780070aa0b54cfd2ac013946b0795d08e6c8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServer.java
@@ -141,11 +141,13 @@ public final class GenericServer extends AbstractServer<IGenericServer> implemen
 
     @Private
     GenericServer(final ISessionManager<Session> sessionManager, final IDAOFactory daoFactory,
+            IPropertiesBatchManager propertiesBatchManager,
             final IGenericBusinessObjectFactory businessObjectFactory,
             final ISampleTypeSlaveServerPlugin sampleTypeSlaveServerPlugin,
             final IDataSetTypeSlaveServerPlugin dataSetTypeSlaveServerPlugin)
     {
-        super(sessionManager, daoFactory, sampleTypeSlaveServerPlugin, dataSetTypeSlaveServerPlugin);
+        super(sessionManager, daoFactory, propertiesBatchManager, sampleTypeSlaveServerPlugin,
+                dataSetTypeSlaveServerPlugin);
         this.businessObjectFactory = businessObjectFactory;
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/IPropertiesBatchManager.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/IPropertiesBatchManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..0bb13c1c0f084f9fc48bdf11f7def27b15a08447
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/IPropertiesBatchManager.java
@@ -0,0 +1,29 @@
+/*
+ * 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.generic.server;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSamplesWithTypes;
+
+/**
+ * Interface of classes which manage managed properties in batch updates.
+ *
+ * @author Franz-Josef Elmer
+ */
+public interface IPropertiesBatchManager
+{
+    public void manageProperties(NewSamplesWithTypes newSamplesWithTypes);
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/PropertiesBatchManager.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/PropertiesBatchManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d9750f10f669c0df704f50af0e8ea496ff40dbb
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/generic/server/PropertiesBatchManager.java
@@ -0,0 +1,162 @@
+/*
+ * 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.generic.server;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import ch.systemsx.cisd.common.evaluator.EvaluatorException;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleTypeDAO;
+import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityProperty;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IPropertiesBean;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSamplesWithTypes;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.ValidationException;
+import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePropertyTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ScriptPE;
+import ch.systemsx.cisd.openbis.generic.shared.managed_property.ManagedPropertyEvaluator;
+
+/**
+ * Handles Managed Properties of batch uploads/updates.
+ *
+ * @author Franz-Josef Elmer
+ */
+public class PropertiesBatchManager implements IPropertiesBatchManager
+{
+    final IDAOFactory daoFactory;
+
+    public PropertiesBatchManager(IDAOFactory daoFactory)
+    {
+        this.daoFactory = daoFactory;
+    }
+
+    public void manageProperties(NewSamplesWithTypes newSamplesWithTypes)
+    {
+        List<NewSample> newSamples = newSamplesWithTypes.getNewSamples();
+        ISampleTypeDAO sampleTypeDAO = daoFactory.getSampleTypeDAO();
+        String code = newSamplesWithTypes.getSampleType().getCode();
+        SampleTypePE sampleType = sampleTypeDAO.tryFindSampleTypeByCode(code);
+        Set<? extends EntityTypePropertyTypePE> sampleTypePropertyTypes =
+                sampleType.getSampleTypePropertyTypes();
+    
+        managePropertiesBeans(newSamples, sampleTypePropertyTypes);
+    }
+    
+    private void managePropertiesBeans(List<? extends IPropertiesBean> propertiesBeans,
+            Set<? extends EntityTypePropertyTypePE> entityTypePropertyTypes)
+    {
+        Map<String, ManagedPropertyEvaluator> evaluators =
+                createEvaluators(entityTypePropertyTypes);
+        for (int i = 0; i < propertiesBeans.size(); i++)
+        {
+            IPropertiesBean propertiesBean = propertiesBeans.get(i);
+            IEntityProperty[] properties = propertiesBean.getProperties();
+            List<IEntityProperty> newProperties = new ArrayList<IEntityProperty>();
+            Map<String, Map<String, String>> subColumnBindings =
+                    createColumnBindingsMap(properties);
+            for (Entry<String, Map<String, String>> entry : subColumnBindings.entrySet())
+            {
+                String code = entry.getKey();
+                Map<String, String> bindings = entry.getValue();
+                ManagedPropertyEvaluator evaluator = evaluators.get(code);
+                EntityProperty entityProperty = new EntityProperty();
+                PropertyType propertyType = new PropertyType();
+                propertyType.setCode(code);
+                propertyType.setDataType(new DataType(DataTypeCode.VARCHAR));
+                entityProperty.setPropertyType(propertyType);
+                if (evaluator == null)
+                {
+                    entityProperty.setValue(bindings.get(""));
+                } else
+                {
+                    try
+                    {
+                        String result = evaluator.updateFromBatchInput(bindings);
+                        entityProperty.setValue(result);
+                    } catch (EvaluatorException ex)
+                    {
+                        Throwable cause = ex.getCause();
+                        if (cause instanceof ValidationException)
+                        {
+                            throw new ValidationException("Error in row " + (i + 1) + ": "
+                                    + cause.getMessage());
+                        }
+                        entityProperty.setValue(BasicConstant.ERROR_PROPERTY_PREFIX
+                                + ex.getMessage());
+                    }
+                }
+                newProperties.add(entityProperty);
+            }
+            propertiesBean.setProperties(newProperties.toArray(new IEntityProperty[newProperties
+                    .size()]));
+        }
+    }
+
+    private Map<String, Map<String, String>> createColumnBindingsMap(IEntityProperty[] properties)
+    {
+        Map<String, Map<String, String>> subColumnBindings =
+                new HashMap<String, Map<String, String>>();
+        for (IEntityProperty property : properties)
+        {
+            String code = property.getPropertyType().getCode().toUpperCase();
+            int indexOfColon = code.indexOf(':');
+            String propertyCode = code;
+            String subColumn = "";
+            if (indexOfColon >= 0)
+            {
+                propertyCode = code.substring(0, indexOfColon);
+                subColumn = code.substring(indexOfColon + 1);
+            }
+            Map<String, String> bindings = subColumnBindings.get(propertyCode);
+            if (bindings == null)
+            {
+                bindings = new HashMap<String, String>();
+                subColumnBindings.put(propertyCode, bindings);
+            }
+            bindings.put(subColumn, property.getValue());
+        }
+        return subColumnBindings;
+    }
+
+    private Map<String, ManagedPropertyEvaluator> createEvaluators(
+            Set<? extends EntityTypePropertyTypePE> entityTypePropertyTypes)
+    {
+        Map<String, ManagedPropertyEvaluator> evaluators =
+                new HashMap<String, ManagedPropertyEvaluator>();
+        for (EntityTypePropertyTypePE entityTypePropertyType : entityTypePropertyTypes)
+        {
+            if (entityTypePropertyType.isManaged())
+            {
+                String propertyTypeCode = entityTypePropertyType.getPropertyType().getCode();
+                ScriptPE script = entityTypePropertyType.getScript();
+                evaluators.put(propertyTypeCode, new ManagedPropertyEvaluator(script.getScript()));
+            }
+        }
+        return evaluators;
+    }
+}   
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServer.java
index 9746b81e8e25229f577be5c3b21d4ef532d5bdbb..9ab7ab75cb70f9871fea5fd0bcac1d8ca8762da3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServer.java
@@ -44,6 +44,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.QueryType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel;
 import ch.systemsx.cisd.openbis.generic.shared.dto.QueryPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 import ch.systemsx.cisd.openbis.plugin.query.shared.DatabaseDefinition;
 import ch.systemsx.cisd.openbis.plugin.query.shared.IQueryDatabaseDefinitionProvider;
 import ch.systemsx.cisd.openbis.plugin.query.shared.IQueryServer;
@@ -79,11 +80,13 @@ public class QueryServer extends AbstractServer<IQueryServer> implements IQueryS
 
     @Private
     QueryServer(final ISessionManager<Session> sessionManager, final IDAOFactory daoFactory,
+            IPropertiesBatchManager propertiesBatchManager,
             final ISampleTypeSlaveServerPlugin sampleTypeSlaveServerPlugin,
             final IDataSetTypeSlaveServerPlugin dataSetTypeSlaveServerPlugin,
             IQueryDatabaseDefinitionProvider dbDefinitionProvider)
     {
-        super(sessionManager, daoFactory, sampleTypeSlaveServerPlugin, dataSetTypeSlaveServerPlugin);
+        super(sessionManager, daoFactory, propertiesBatchManager, sampleTypeSlaveServerPlugin,
+                dataSetTypeSlaveServerPlugin);
         this.dbDefinitionProvider = dbDefinitionProvider;
     }
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
index 26a4a4bfe4e015404512d95cda586ab781f05604..a66aed46d1488f3d6c0e4a84ddfe722236372ee9 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java
@@ -114,7 +114,8 @@ public final class CommonServerTest extends AbstractServerTestCase
     {
         CommonServer server =
                 new CommonServer(authenticationService, sessionManager, daoFactory,
-                        commonBusinessObjectFactory, new LastModificationState());
+                        propertiesBatchManager, commonBusinessObjectFactory,
+                        new LastModificationState());
         server.setSampleTypeSlaveServerPlugin(sampleTypeSlaveServerPlugin);
         server.setDataSetTypeSlaveServerPlugin(dataSetTypeSlaveServerPlugin);
         server.setBaseIndexURL(SESSION_TOKEN, BASE_INDEX_URL);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java
index 719799a8264644079325bc993ae0ec9468d3b87b..c37197ed752b775912f155dcf51340de59c10945 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java
@@ -899,8 +899,8 @@ public class ETLServiceTest extends AbstractServerTestCase
 
     private IETLLIMSService createService()
     {
-        return new ETLService(authenticationService, sessionManager, daoFactory, boFactory,
-                dssfactory);
+        return new ETLService(authenticationService, sessionManager, daoFactory,
+                propertiesBatchManager, boFactory, dssfactory);
     }
 
     private DataStoreServerInfo createDSSInfo()
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceTest.java
index d3cac9d9e0b6874a405a49022329c3c9585866fe..8af35e94c7bf6fe41ffa94b89f948fe7ad0778a0 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/api/v1/GeneralInformationServiceTest.java
@@ -76,7 +76,9 @@ public class GeneralInformationServiceTest extends AbstractServerTestCase
     {
         super.setUp();
         commonServer = context.mock(ICommonServer.class);
-        service = new GeneralInformationService(sessionManager, daoFactory, commonServer);
+        service =
+                new GeneralInformationService(sessionManager, daoFactory, propertiesBatchManager,
+                        commonServer);
     }
 
     @Test
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java
index f9d9330a22cc01fddf03ea242cb2eadc6a34ae5a..368e80c69d8a11876f9c6cfa60a3039cb380cb23 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java
@@ -58,7 +58,6 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExperimentDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IExternalDataDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IFileFormatTypeDAO;
-import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISpaceDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IPersonDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IProjectDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IPropertyTypeDAO;
@@ -66,6 +65,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IQueryDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IRoleAssignmentDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleTypeDAO;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISpaceDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IVocabularyDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.IPermIdDAO;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DisplaySettings;
@@ -73,10 +73,11 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 
 /**
  * An <i>abstract</i> test infrastructure for {@link IServer} implementations.
@@ -175,6 +176,8 @@ public abstract class AbstractServerTestCase extends AssertJUnit
 
     protected IDynamicPropertyEvaluationScheduler evaluator;
 
+    protected IPropertiesBatchManager propertiesBatchManager;
+
     @BeforeMethod
     @SuppressWarnings("unchecked")
     public void setUp()
@@ -184,6 +187,7 @@ public abstract class AbstractServerTestCase extends AssertJUnit
         context = new Mockery();
         authenticationService = context.mock(IAuthenticationService.class);
         sessionManager = context.mock(ISessionManager.class);
+        propertiesBatchManager = context.mock(IPropertiesBatchManager.class);
         // DAO
         daoFactory = context.mock(IDAOFactory.class);
         databaseInstanceDAO = context.mock(IDatabaseInstanceDAO.class);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServerTest.java
index 251703464e207502573b0f5073df07663de3d7cc..58f5355984408da91e869b6da05ea74b269d623d 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/demo/server/DemoServerTest.java
@@ -23,6 +23,7 @@ import ch.systemsx.cisd.openbis.generic.server.plugin.IDataSetTypeSlaveServerPlu
 import ch.systemsx.cisd.openbis.generic.server.plugin.ISampleTypeSlaveServerPlugin;
 import ch.systemsx.cisd.openbis.generic.shared.AbstractServerTestCase;
 import ch.systemsx.cisd.openbis.plugin.demo.shared.IDemoServer;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 
 /**
  * Test cases for corresponding {@link DemoServer} class.
@@ -38,11 +39,14 @@ public final class DemoServerTest extends AbstractServerTestCase
 
     private IDataSetTypeSlaveServerPlugin dataSetTypeSlaveServerPlugin;
 
+    private IPropertiesBatchManager propertiesBatchManager;
+
     @SuppressWarnings("unused")
     private final IDemoServer createServer()
     {
-        return new DemoServer(sessionManager, daoFactory, demoBusinessObjectFactory,
-                sampleTypeSlaveServerPlugin, dataSetTypeSlaveServerPlugin);
+        return new DemoServer(sessionManager, daoFactory, propertiesBatchManager,
+                demoBusinessObjectFactory, sampleTypeSlaveServerPlugin,
+                dataSetTypeSlaveServerPlugin);
     }
 
     //
@@ -57,5 +61,7 @@ public final class DemoServerTest extends AbstractServerTestCase
         sampleTypeSlaveServerPlugin = context.mock(ISampleTypeSlaveServerPlugin.class);
         demoBusinessObjectFactory = context.mock(IDemoBusinessObjectFactory.class);
         dataSetTypeSlaveServerPlugin = context.mock(IDataSetTypeSlaveServerPlugin.class);
+        propertiesBatchManager = context.mock(IPropertiesBatchManager.class);
+
     }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerTest.java
index 356a37d1dc94882c6292f87e819f9cc2f2d1bfcf..522eabd5cc2fb1bdb50e66402d954ebef02d893b 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/server/GenericServerTest.java
@@ -110,8 +110,9 @@ public final class GenericServerTest extends AbstractServerTestCase
     private final IGenericServer createServer()
     {
         GenericServer genericServer =
-                new GenericServer(sessionManager, daoFactory, genericBusinessObjectFactory,
-                        sampleTypeSlaveServerPlugin, dataSetTypeSlaveServerPlugin);
+                new GenericServer(sessionManager, daoFactory, propertiesBatchManager,
+                        genericBusinessObjectFactory, sampleTypeSlaveServerPlugin,
+                        dataSetTypeSlaveServerPlugin);
         genericServer.commonServer = commonServer;
         return genericServer;
     }
@@ -248,7 +249,15 @@ public final class GenericServerTest extends AbstractServerTestCase
         newSamples.add(createNewSample("same"));
         newSamples.add(createNewSample("same"));
         List<NewSamplesWithTypes> samplesWithTypes = new ArrayList<NewSamplesWithTypes>();
-        samplesWithTypes.add(new NewSamplesWithTypes(new SampleType(), newSamples));
+        final NewSamplesWithTypes newSamplesWithType = new NewSamplesWithTypes(new SampleType(), newSamples);
+        samplesWithTypes.add(newSamplesWithType);
+        context.checking(new Expectations()
+            {
+                {
+                    one(propertiesBatchManager).manageProperties(newSamplesWithType);
+                }
+            });
+        
         try
         {
             server.registerSamples(SESSION_TOKEN, samplesWithTypes);
@@ -271,7 +280,8 @@ public final class GenericServerTest extends AbstractServerTestCase
         newSamples.add(createNewSample("one"));
         newSamples.add(createNewSample("two"));
         List<NewSamplesWithTypes> samplesWithTypes = new ArrayList<NewSamplesWithTypes>();
-        samplesWithTypes.add(new NewSamplesWithTypes(sampleType, newSamples));
+        final NewSamplesWithTypes newSamplesWithType = new NewSamplesWithTypes(sampleType, newSamples);
+        samplesWithTypes.add(newSamplesWithType);
         context.checking(new Expectations()
             {
                 {
@@ -279,6 +289,8 @@ public final class GenericServerTest extends AbstractServerTestCase
                     will(returnValue(sampleTypePE));
 
                     one(sampleTypeSlaveServerPlugin).registerSamples(SESSION, newSamples, null);
+                    
+                    one(propertiesBatchManager).manageProperties(newSamplesWithType);
                 }
             });
         createServer().registerOrUpdateSamples(SESSION_TOKEN, samplesWithTypes);
@@ -296,7 +308,9 @@ public final class GenericServerTest extends AbstractServerTestCase
         newSamples.add(createNewSample("one"));
         newSamples.add(createNewSample("two"));
         List<NewSamplesWithTypes> samplesWithTypes = new ArrayList<NewSamplesWithTypes>();
-        samplesWithTypes.add(new NewSamplesWithTypes(sampleType, newSamples));
+        final NewSamplesWithTypes newSamplesWithType =
+                new NewSamplesWithTypes(sampleType, newSamples);
+        samplesWithTypes.add(newSamplesWithType);
         context.checking(new Expectations()
             {
                 {
@@ -304,6 +318,8 @@ public final class GenericServerTest extends AbstractServerTestCase
                     will(returnValue(sampleTypePE));
 
                     one(sampleTypeSlaveServerPlugin).registerSamples(SESSION, newSamples, null);
+                    
+                    one(propertiesBatchManager).manageProperties(newSamplesWithType);
                 }
             });
         createServer().registerSamples(SESSION_TOKEN, samplesWithTypes);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServerTest.java
index 1eba9fd9dbbc6142f43c8f18daba466414727190..782d7066c7f859de3b20ae045b950009d9f29d58 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServerTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/query/server/QueryServerTest.java
@@ -62,8 +62,8 @@ public final class QueryServerTest extends AbstractServerTestCase
 
     private final IQueryServer createServer()
     {
-        return new QueryServer(sessionManager, daoFactory, sampleTypeSlaveServerPlugin,
-                dataSetTypeSlaveServerPlugin, dbDefinitionProvider);
+        return new QueryServer(sessionManager, daoFactory, propertiesBatchManager,
+                sampleTypeSlaveServerPlugin, dataSetTypeSlaveServerPlugin, dbDefinitionProvider);
     }
 
     //
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 8caa9faee0aaa00b39d5256e805c43bfdb608ce5..ebfcb25bec61cc023c83bc84ce9f8d5a99f47927 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
@@ -39,6 +39,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
 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.VocabularyTranslator;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.AccessionNumberBuilder;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.IAbundanceColumnDefinitionTable;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.IBusinessObjectFactory;
@@ -83,11 +84,13 @@ public class PhosphoNetXServer extends AbstractServer<IPhosphoNetXServer> implem
 
     @Private
     PhosphoNetXServer(ISessionManager<Session> sessionManager, IDAOFactory daoFactory,
+            IPropertiesBatchManager propertiesBatchManager,
             IPhosphoNetXDAOFactory specificDAOFactory, IBusinessObjectFactory specificBOFactory,
             ISampleTypeSlaveServerPlugin sampleTypeSlaveServerPlugin,
             IDataSetTypeSlaveServerPlugin dataSetTypeSlaveServerPlugin)
     {
-        super(sessionManager, daoFactory, sampleTypeSlaveServerPlugin, dataSetTypeSlaveServerPlugin);
+        super(sessionManager, daoFactory, propertiesBatchManager, sampleTypeSlaveServerPlugin,
+                dataSetTypeSlaveServerPlugin);
         this.specificDAOFactory = specificDAOFactory;
         this.specificBOFactory = specificBOFactory;
     }
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/ProteomicsDataServiceInternal.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/ProteomicsDataServiceInternal.java
index ba4b3efca6417b3e337360f41887983a1d9c8130..5673cf414a7bb47b4996d2480931c0078767a7fc 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/ProteomicsDataServiceInternal.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/ProteomicsDataServiceInternal.java
@@ -52,6 +52,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind;
 import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.ExperimentLoader;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.IBusinessObjectFactory;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.server.business.ISampleLoader;
@@ -94,7 +95,14 @@ public class ProteomicsDataServiceInternal extends AbstractServer<IProteomicsDat
     public ProteomicsDataServiceInternal(ISessionManager<Session> sessionManager, IDAOFactory daoFactory,
             ICommonBusinessObjectFactory businessObjectFactory, IBusinessObjectFactory boFactory)
     {
-        super(sessionManager, daoFactory);
+        this(sessionManager, daoFactory, null, businessObjectFactory, boFactory);
+    }
+    
+    ProteomicsDataServiceInternal(ISessionManager<Session> sessionManager, IDAOFactory daoFactory,
+            IPropertiesBatchManager propertiesBatchManager,
+            ICommonBusinessObjectFactory businessObjectFactory, IBusinessObjectFactory boFactory)
+    {
+        super(sessionManager, daoFactory, propertiesBatchManager);
         sessionManagerFromConstructor = sessionManager;
         this.commonBoFactory = businessObjectFactory;
         this.boFactory = boFactory;
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/ProteomicsDataService.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/ProteomicsDataService.java
index b69fbe54a8c02410bb05fb347353d11ec5eca508..24707207de229d0a9fac3480333169a945310e8b 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/ProteomicsDataService.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/ProteomicsDataService.java
@@ -48,6 +48,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServicePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SessionContextDTO;
 import ch.systemsx.cisd.openbis.generic.shared.util.DataTypeUtils;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.IProteomicsDataServiceInternal;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.IProteomicsDataService;
 import ch.systemsx.cisd.openbis.plugin.phosphonetx.shared.api.v1.dto.DataSet;
@@ -75,9 +76,10 @@ public class ProteomicsDataService extends AbstractServer<IProteomicsDataService
     }
 
     public ProteomicsDataService(final ISessionManager<Session> sessionManager,
-            final IDAOFactory daoFactory, IProteomicsDataServiceInternal service)
+            final IDAOFactory daoFactory, IPropertiesBatchManager propertiesBatchManager,
+            IProteomicsDataServiceInternal service)
     {
-        super(sessionManager, daoFactory);
+        super(sessionManager, daoFactory, propertiesBatchManager);
         this.service = service;
     }
 
diff --git a/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServerTest.java b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServerTest.java
index 32ea695b4701ccd59d81d3d55179dc0ab7276459..b1f8fdd9ec3fce46c88c7a96f27be125bc1b5045 100644
--- a/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServerTest.java
+++ b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/PhosphoNetXServerTest.java
@@ -69,8 +69,9 @@ public class PhosphoNetXServerTest extends AbstractServerTestCase
         abundanceColumnDefinitionTable = context.mock(IAbundanceColumnDefinitionTable.class);
         sampleProvider = context.mock(ISampleProvider.class);
         server =
-                new PhosphoNetXServer(sessionManager, daoFactory, phosphoNetXDAOFactory, boFactory,
-                        sampleTypeSlaveServerPlugin, dataSetTypeSlaveServerPlugin);
+                new PhosphoNetXServer(sessionManager, daoFactory, propertiesBatchManager,
+                        phosphoNetXDAOFactory, boFactory, sampleTypeSlaveServerPlugin,
+                        dataSetTypeSlaveServerPlugin);
         context.checking(new Expectations()
             {
                 {
diff --git a/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/ProteomicsDataServiceInternalTest.java b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/ProteomicsDataServiceInternalTest.java
index 746a449c2cc7b76f4b972bc34f1a4ecd91254b1d..b8f168f569e8b7a3f8dd24697cce3280495affc8 100644
--- a/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/ProteomicsDataServiceInternalTest.java
+++ b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/ProteomicsDataServiceInternalTest.java
@@ -94,7 +94,9 @@ public class ProteomicsDataServiceInternalTest extends AbstractServerTestCase
         commonBoFactory = context.mock(ICommonBusinessObjectFactory.class);
         boFactory = context.mock(IBusinessObjectFactory.class);
         sampleLoader = context.mock(ISampleLoader.class);
-        service = new ProteomicsDataServiceInternal(sessionManager, daoFactory, commonBoFactory, boFactory);
+        service =
+                new ProteomicsDataServiceInternal(sessionManager, daoFactory,
+                        propertiesBatchManager, commonBoFactory, boFactory);
         experimentType = new ExperimentTypePE();
         experimentType.setCode(EXPERIMENT_TYPE);
         experimentType.setDatabaseInstance(CommonTestUtils.createHomeDatabaseInstance());
diff --git a/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/ProteomicsDataServiceTest.java b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/ProteomicsDataServiceTest.java
index 8400078039096c118ecb39c71168e11c91b20a58..fd3133c5def4172f4a04e4ec33d014f4fe3e22bf 100644
--- a/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/ProteomicsDataServiceTest.java
+++ b/rtd_phosphonetx/sourceTest/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/server/api/v1/ProteomicsDataServiceTest.java
@@ -80,7 +80,9 @@ public class ProteomicsDataServiceTest extends AbstractServerTestCase
     {
         super.setUp();
         internalService = context.mock(IProteomicsDataServiceInternal.class);
-        service = new ProteomicsDataService(sessionManager, daoFactory, internalService);
+        service =
+                new ProteomicsDataService(sessionManager, daoFactory, propertiesBatchManager,
+                        internalService);
         session2 = new SessionContextDTO();
         session2.setSessionToken(SESSION_TOKEN + "2");
     }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java
index 00fb39aa2220a66ec76fb3dd1b36780691e801b4..94d68c2e9e290e8e6e0cf7723493edd60c3eeca5 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServer.java
@@ -62,6 +62,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SessionContextDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE;
 import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.VocabularyTranslator;
+import ch.systemsx.cisd.openbis.plugin.generic.server.IPropertiesBatchManager;
 import ch.systemsx.cisd.openbis.plugin.generic.shared.IGenericServer;
 import ch.systemsx.cisd.openbis.plugin.screening.server.dataaccess.IScreeningQuery;
 import ch.systemsx.cisd.openbis.plugin.screening.server.logic.PlateContentLoader;
@@ -124,11 +125,13 @@ public final class ScreeningServer extends AbstractServer<IScreeningServer> impl
 
     @Private
     ScreeningServer(final ISessionManager<Session> sessionManager, final IDAOFactory daoFactory,
+            IPropertiesBatchManager propertiesBatchManager,
             final IScreeningBusinessObjectFactory businessObjectFactory,
             final ISampleTypeSlaveServerPlugin sampleTypeSlaveServerPlugin,
             final IDataSetTypeSlaveServerPlugin dataSetTypeSlaveServerPlugin)
     {
-        super(sessionManager, daoFactory, sampleTypeSlaveServerPlugin, dataSetTypeSlaveServerPlugin);
+        super(sessionManager, daoFactory, propertiesBatchManager, sampleTypeSlaveServerPlugin,
+                dataSetTypeSlaveServerPlugin);
         this.businessObjectFactory = businessObjectFactory;
     }