diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
index ee73c5586133590b8c8282ccf7dba3aa4c6dc776..358207f6f6848aab3e1efc2eeb3976a969321dec 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientService.java
@@ -54,6 +54,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DynamicPropertyEvaluationInfo;
 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.EntityTypePropertyType;
@@ -929,4 +930,9 @@ public interface ICommonClientService extends IClientService
      * Returns script with given {@link TechId}.
      */
     public Script getScriptInfo(TechId scriptId) throws UserFailureException;
+
+    /**
+     * Returns script evaluation result.
+     */
+    public String evaluate(DynamicPropertyEvaluationInfo info) throws UserFailureException;
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
index c05f4598351a4dfc8e3fd7c063d76e1bf64d2120..8beb34676b6631bdf14263714de1a2e4a5276182 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/ICommonClientServiceAsync.java
@@ -56,6 +56,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DynamicPropertyEvaluationInfo;
 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.EntityTypePropertyType;
@@ -822,4 +823,10 @@ public interface ICommonClientServiceAsync extends IClientServiceAsync
      */
     public void getScriptInfo(TechId scriptId, AsyncCallback<Script> scriptInfoCallback);
 
+    /**
+     * @see ICommonClientService#evaluate(DynamicPropertyEvaluationInfo)
+     */
+    public void evaluate(DynamicPropertyEvaluationInfo dynamicPropertyEvaluationInfo,
+            AsyncCallback<String> callback);
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
index 80e0cdf04b1dc65c3e20c1f0a5a36d6042d0cd6b..c9e68e143170b084e51714869020a86da88101f8 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/Dict.java
@@ -1010,5 +1010,21 @@ public abstract class Dict
 
     public static final String MATERIAL_PROPERTIES_HEADING = "material_properties_heading";
 
+    public static final String BUTTON_EVALUATE = "button_evaluate";
+
+    public static final String EVALUATION_RESULT = "evaluation_result";
+
+    public static final String SCRIPT_TESTER = "script_tester";
+
+    public static final String ENTITY_DETAILS = "entity_details";
+
+    public static final String SHOW_DETAILS = "show_details";
+
+    public static final String EVALUATION_IN_PROGRESS = "evaluation_in_progress";
+
+    public static final String WARNING_NO_SCRIPT_TITLE = "warning_no_script_title";
+
+    public static final String WARNING_NO_SCRIPT_MESSAGE = "warning_no_script_message";
+
     // ----- end generic ------------------
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/SampleTypeDisplayID.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/SampleTypeDisplayID.java
index 33dd63971e148c83eb2fcf55208ddf07f0d8b965..ec8af1d819c13e0792fb3418299f9353cbec9409 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/SampleTypeDisplayID.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/framework/SampleTypeDisplayID.java
@@ -35,6 +35,8 @@ public enum SampleTypeDisplayID
 
     DATA_SET_EDIT_SAMPLE_CHOOSER("data_set_edit_sample_chooser", false),
 
+    SCRIPT_EDITOR_SAMPLE_CHOOSER("script_editor_sample_chooser", false),
+
     EXPERIMENT_REGISTRATION("experiment_registration", false),
 
     PROPERTY_ASSIGNMENT("property_assignment", false),
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/AbstractRegistrationForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/AbstractRegistrationForm.java
index a558922cf590203c2104283c9ee99552a8cf133b..d2441302fd7ba3950f0ae8356c01f12cf106ebf9 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/AbstractRegistrationForm.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/AbstractRegistrationForm.java
@@ -27,12 +27,13 @@ import com.extjs.gxt.ui.client.event.Listener;
 import com.extjs.gxt.ui.client.event.SelectionListener;
 import com.extjs.gxt.ui.client.widget.ContentPanel;
 import com.extjs.gxt.ui.client.widget.Html;
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
 import com.extjs.gxt.ui.client.widget.button.Button;
 import com.extjs.gxt.ui.client.widget.form.Field;
 import com.extjs.gxt.ui.client.widget.form.FormPanel;
-import com.extjs.gxt.ui.client.widget.form.HiddenField;
 import com.extjs.gxt.ui.client.widget.form.FormPanel.Encoding;
 import com.extjs.gxt.ui.client.widget.form.FormPanel.Method;
+import com.extjs.gxt.ui.client.widget.form.HiddenField;
 import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
 import com.google.gwt.core.client.JavaScriptException;
 import com.google.gwt.event.dom.client.ClickEvent;
@@ -46,6 +47,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.InfoBoxCal
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.ClickableFormPanel;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.InfoBox;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IMessageProvider;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.WidgetUtils;
 import ch.systemsx.cisd.openbis.generic.shared.basic.IIdAndCodeHolder;
 
 /**
@@ -55,7 +57,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.IIdAndCodeHolder;
  */
 public abstract class AbstractRegistrationForm extends ContentPanel
 {
-    private static final int PANEL_MARGIN = 100;
+    public static final int PANEL_MARGIN = 100;
 
     private static final String SESSION_KEY_PREFIX = "sessionKey_";
 
@@ -89,6 +91,8 @@ public abstract class AbstractRegistrationForm extends ContentPanel
 
     private Html loadingInfo;
 
+    protected LayoutContainer rightPanel;
+
     protected AbstractRegistrationForm(final IMessageProvider messageProvider, final String id)
     {
         this(messageProvider, id, DEFAULT_LABEL_WIDTH, DEFAULT_FIELD_WIDTH);
@@ -107,7 +111,17 @@ public abstract class AbstractRegistrationForm extends ContentPanel
         setId(id);
         add(infoBox = createInfoBox());
         add(loadingInfo = createLoadingInfo());
-        add(formPanel = createFormPanel(messageProvider));
+        add(WidgetUtils.inRow(formPanel = createFormPanel(messageProvider), rightPanel =
+                createAdditionalPanel()));
+    }
+
+    private LayoutContainer createAdditionalPanel()
+    {
+        LayoutContainer c = new LayoutContainer();
+        c.setLayout(new FlowLayout(5));
+        c.setBorders(false);
+        c.setScrollMode(Scroll.AUTO);
+        return c;
     }
 
     private Html createLoadingInfo()
@@ -326,8 +340,8 @@ public abstract class AbstractRegistrationForm extends ContentPanel
     public static String getEditTitle(final IMessageProvider messageProvider,
             final String entityKindDictKey, final IIdAndCodeHolder identifiable)
     {
-        return messageProvider.getMessage(Dict.EDIT_TITLE, messageProvider
-                .getMessage(entityKindDictKey), identifiable.getCode());
+        return messageProvider.getMessage(Dict.EDIT_TITLE,
+                messageProvider.getMessage(entityKindDictKey), identifiable.getCode());
     }
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetSearchHitGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetSearchHitGrid.java
index fd24d4f79f53bf13f137201203e92fbf5cc99283..c53c020dc78c3b5fe5e3b0adc7b62cf1efe38613 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetSearchHitGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/data/DataSetSearchHitGrid.java
@@ -27,6 +27,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewConte
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ShowResultSetCutInfo;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DisplayTypeIDGenerator;
 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.DisposableEntityChooser;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IDisposableComponent;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.search.DetailedSearchToolbar;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.search.DetailedSearchWindow;
@@ -66,7 +67,7 @@ public class DataSetSearchHitGrid extends AbstractExternalDataGrid implements
         return grid.asDisposableWithToolbar(toolbar);
     }
 
-    public static IDisposableComponent createWithInitialSearchCriteria(
+    public static DisposableEntityChooser<ExternalData> createWithInitialSearchCriteria(
             final IViewContext<ICommonClientServiceAsync> viewContext,
             DetailedSearchCriteria searchCriteria)
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/ChosenEntitySetter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/ChosenEntitySetter.java
index fa4c4f2075d5b54adc065d8896a876f60d4f37d6..94de7a20a8af58d2f77f41c12ed315e44d2e2c85 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/ChosenEntitySetter.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/ChosenEntitySetter.java
@@ -21,7 +21,8 @@ import java.util.Set;
 
 import com.extjs.gxt.ui.client.widget.form.TriggerField;
 
-abstract class ChosenEntitySetter<T> extends TriggerField<String> implements IChosenEntitySetter<T>
+public abstract class ChosenEntitySetter<T> extends TriggerField<String> implements
+        IChosenEntitySetter<T>
 {
     private static final int TEXT_CHOOSER_FIELD_WIDTH = 342;
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/DataSetChooserField.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/DataSetChooserField.java
new file mode 100644
index 0000000000000000000000000000000000000000..190447a8dc1491ed4170862db39cb73793cbfb33
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/DataSetChooserField.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2008 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field;
+
+import java.util.ArrayList;
+
+import com.extjs.gxt.ui.client.event.ComponentEvent;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.data.DataSetSearchHitGrid;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.DisposableEntityChooser;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil;
+import ch.systemsx.cisd.openbis.generic.shared.basic.AttributeSearchFieldKindProvider;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriterion;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchField;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchCriteriaConnection;
+
+/**
+ * A field for selecting a data set from a list.
+ * 
+ * @author Izabela Adamczyk
+ */
+public class DataSetChooserField extends ChosenEntitySetter<ExternalData>
+{
+    public static DataSetChooserField create(final String labelField, final boolean mandatory,
+            final IViewContext<ICommonClientServiceAsync> viewContext)
+    {
+        final DataSetChooserField field = new DataSetChooserField(mandatory, viewContext)
+            {
+                @Override
+                protected void onTriggerClick(ComponentEvent ce)
+                {
+                    super.onTriggerClick(ce);
+                    browse(viewContext, this);
+                }
+            };
+
+        field.setFieldLabel(labelField);
+        return field;
+    }
+
+    private static void browse(final IViewContext<ICommonClientServiceAsync> viewContext,
+            final ChosenEntitySetter<ExternalData> field)
+    {
+        ArrayList<DetailedSearchCriterion> criterionList = new ArrayList<DetailedSearchCriterion>();
+        DetailedSearchCriteria searchCriteria = new DetailedSearchCriteria();
+        searchCriteria.setConnection(SearchCriteriaConnection.MATCH_ANY);
+        DetailedSearchCriterion searchCriterion =
+                new DetailedSearchCriterion(
+                        DetailedSearchField.createAttributeField(AttributeSearchFieldKindProvider
+                                .getAttributeFieldKind(EntityKind.DATA_SET, "CODE")), "*");
+        criterionList.add(searchCriterion);
+        searchCriteria.setCriteria(criterionList);
+        DisposableEntityChooser<ExternalData> browser =
+                DataSetSearchHitGrid.createWithInitialSearchCriteria(viewContext, searchCriteria);
+        new EntityChooserDialog<ExternalData>(browser, field, "Choose data set", viewContext)
+                .show();
+    }
+
+    @Override
+    public String renderEntity(ExternalData entity)
+    {
+        return entity.getCode();
+    }
+
+    private DataSetChooserField(boolean mandatory,
+            IViewContext<ICommonClientServiceAsync> viewContext)
+    {
+        FieldUtil.setMandatoryFlag(this, mandatory);
+        setValidateOnBlur(true);
+        setAutoValidate(true);
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/MaterialChooserField.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/MaterialChooserField.java
index f9bb7a2ada66e86f0e49ed36e494d13881a3ffc6..016e7738e80f7bc68ee477095840350c51807c52 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/MaterialChooserField.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/field/MaterialChooserField.java
@@ -17,7 +17,6 @@
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field;
 
 import com.extjs.gxt.ui.client.event.ComponentEvent;
-import com.extjs.gxt.ui.client.widget.form.Field;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
@@ -37,7 +36,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType;
  */
 public class MaterialChooserField extends ChosenEntitySetter<Material>
 {
-    public static Field<?> create(final String labelField, final boolean mandatory,
+    public static MaterialChooserField create(final String labelField, final boolean mandatory,
             final MaterialType materialTypeOrNull, String initialValueOrNull,
             final IViewContext<ICommonClientServiceAsync> viewContext)
     {
@@ -70,8 +69,8 @@ public class MaterialChooserField extends ChosenEntitySetter<Material>
     // ------------------
 
     // the pattern used to validate material identifier expression
-    private final static String CODE_AND_TYPE_PATTERN =
-            CodeField.CODE_CHARS + " " + "\\(" + CodeField.CODE_CHARS + "\\)";
+    private final static String CODE_AND_TYPE_PATTERN = CodeField.CODE_CHARS + " " + "\\("
+            + CodeField.CODE_CHARS + "\\)";
 
     @Override
     public String renderEntity(Material materialOrNull)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/listener/OpenEntityDetailsTabClickListener.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/listener/OpenEntityDetailsTabClickListener.java
index e27b193e9ba75da90c3d67ed749ce1f0764ce4f2..1d4d0655f09f361163d5efae84d1259ce7e4e497 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/listener/OpenEntityDetailsTabClickListener.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/listener/OpenEntityDetailsTabClickListener.java
@@ -28,7 +28,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWit
  * 
  * @author Piotr Buczek
  */
-public final class OpenEntityDetailsTabClickListener implements ClickHandler
+public class OpenEntityDetailsTabClickListener implements ClickHandler
 {
     private final IEntityInformationHolderWithPermId entity;
 
@@ -42,9 +42,14 @@ public final class OpenEntityDetailsTabClickListener implements ClickHandler
         this.viewContext = viewContext;
     }
 
+    protected IEntityInformationHolderWithPermId getEntity()
+    {
+        return entity;
+    }
+
     public void onClick(ClickEvent event)
     {
-        new OpenEntityDetailsTabAction(entity, viewContext, WidgetUtils.ifSpecialKeyPressed(event
-                .getNativeEvent())).execute();
+        new OpenEntityDetailsTabAction(getEntity(), viewContext,
+                WidgetUtils.ifSpecialKeyPressed(event.getNativeEvent())).execute();
     }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/AbstractScriptEditRegisterForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/AbstractScriptEditRegisterForm.java
index 823e2a5c15d2987abb288655d3313dc1a4f80360..59559425dc479feccb7c87045361fba3fbc65f68 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/AbstractScriptEditRegisterForm.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/AbstractScriptEditRegisterForm.java
@@ -16,10 +16,12 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.script;
 
+import com.extjs.gxt.ui.client.event.BaseEvent;
 import com.extjs.gxt.ui.client.event.ButtonEvent;
+import com.extjs.gxt.ui.client.event.Events;
+import com.extjs.gxt.ui.client.event.Listener;
 import com.extjs.gxt.ui.client.event.SelectionListener;
-import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
-import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
+import com.extjs.gxt.ui.client.widget.form.FormPanel;
 import com.extjs.gxt.ui.client.widget.form.TextField;
 import com.google.gwt.user.client.Element;
 
@@ -33,9 +35,9 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.M
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.ScriptField;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.VarcharField;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.AbstractRegistrationDialog;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Script;
 
 /**
  * {@link AbstractRegistrationForm} for registering and editing scripts.
@@ -53,12 +55,16 @@ abstract public class AbstractScriptEditRegisterForm extends AbstractRegistratio
 
     protected final MultilineVarcharField scriptField;
 
-    protected SimpleComboBox<String> entityKindField;
+    protected EntityKindSelectionWidget entityKindField;
+
+    private ScriptExecutionFramework scriptExecution;
 
     abstract protected void saveScript();
 
     abstract protected void setValues();
 
+    abstract protected Script getScript();
+
     protected AbstractScriptEditRegisterForm(
             final IViewContext<ICommonClientServiceAsync> viewContext, EntityKind entityKindOrNull)
     {
@@ -72,34 +78,31 @@ abstract public class AbstractScriptEditRegisterForm extends AbstractRegistratio
         super(viewContext, createId(scriptIdOrNull), DEFAULT_LABEL_WIDTH + 20, DEFAULT_FIELD_WIDTH);
         this.viewContext = viewContext;
         this.nameField = new VarcharField(viewContext.getMessage(Dict.NAME), true);
-        this.entityKindField = createEntityKindOrAllField(entityKindOrNull, scriptIdOrNull == null);
+        this.entityKindField =
+                new EntityKindSelectionWidget(viewContext, entityKindOrNull,
+                        scriptIdOrNull == null, true);
         this.descriptionField = AbstractRegistrationDialog.createDescriptionField(viewContext);
         this.scriptField = createScriptField(viewContext);
+        this.scriptExecution = new ScriptExecutionFramework(viewContext, asValidable(formPanel));
+        scriptField.addListener(Events.Change, new Listener<BaseEvent>()
+            {
+                public void handleEvent(BaseEvent be)
+                {
+                    scriptExecution.update(scriptField.getValue());
+                }
+            });
     }
 
-    private SimpleComboBox<String> createEntityKindOrAllField(EntityKind entityKindOrNull,
-            boolean enabled)
+    private IValidable asValidable(final FormPanel panel)
     {
-        SimpleComboBox<String> options = new SimpleComboBox<String>();
-        options.add(GenericConstants.ALL_ENTITY_KINDS);
-        if (entityKindOrNull != null)
-        {
-            options.add(entityKindOrNull.name());
-        } else
-        {
-            for (EntityKind val : EntityKind.values())
+        return new IValidable()
             {
-                options.add(val.name());
-            }
-        }
-        options.setFieldLabel(viewContext.getMessage(Dict.ENTITY_KIND));
-        options.setTriggerAction(TriggerAction.ALL);
-        options.setForceSelection(true);
-        options.setEditable(false);
-        options.setAllowBlank(false);
-        FieldUtil.markAsMandatory(options);
-        options.setEnabled(enabled);
-        return options;
+
+                public boolean isValid()
+                {
+                    return panel.isValid();
+                }
+            };
     }
 
     private static MultilineVarcharField createScriptField(
@@ -107,6 +110,7 @@ abstract public class AbstractScriptEditRegisterForm extends AbstractRegistratio
     {
         final MultilineVarcharField field = new ScriptField(viewContext);
         field.treatTabKeyAsInput();
+        field.setFireChangeEventOnSetValue(true);
         return field;
     }
 
@@ -129,6 +133,7 @@ abstract public class AbstractScriptEditRegisterForm extends AbstractRegistratio
         formPanel.add(entityKindField);
         formPanel.add(descriptionField);
         formPanel.add(scriptField);
+        rightPanel.add(scriptExecution.getWidget());
         redefineSaveListeners();
     }
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/EntityKindSelectionWidget.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/EntityKindSelectionWidget.java
new file mode 100644
index 0000000000000000000000000000000000000000..81fe5ccf5972dc99d7ddfa617b464830f6874d78
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/EntityKindSelectionWidget.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.script;
+
+import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
+
+import ch.systemsx.cisd.common.shared.basic.utils.StringUtils;
+import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
+
+/**
+ * @author Izabela Adamczyk
+ */
+class EntityKindSelectionWidget extends SimpleComboBox<String>
+{
+    public EntityKindSelectionWidget(IViewContext<ICommonClientServiceAsync> viewContext,
+            EntityKind entityKindOrNull, boolean enabled, boolean withAll)
+    {
+        if (withAll)
+        {
+            add(GenericConstants.ALL_ENTITY_KINDS);
+        }
+        if (entityKindOrNull != null)
+        {
+            add(entityKindOrNull.name());
+        } else
+        {
+            for (EntityKind val : EntityKind.values())
+            {
+                add(val.name());
+            }
+        }
+        setFieldLabel(viewContext.getMessage(Dict.ENTITY_KIND));
+        setTriggerAction(TriggerAction.ALL);
+        setForceSelection(true);
+        setEditable(false);
+        setAllowBlank(false);
+        FieldUtil.markAsMandatory(this);
+        setEnabled(enabled);
+    }
+
+    public boolean isAllEntityKindsSelected()
+    {
+        return (StringUtils.isBlank(getSimpleValue()) == false)
+                && getSimpleValue().equals(GenericConstants.ALL_ENTITY_KINDS);
+    }
+
+    public EntityKind tryGetEntityKind()
+    {
+        String simpleValue = getSimpleValue();
+        if (StringUtils.isBlank(simpleValue) || isAllEntityKindsSelected())
+        {
+            return null;
+        } else
+        {
+            return EntityKind.valueOf(simpleValue);
+        }
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/IValidable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/IValidable.java
new file mode 100644
index 0000000000000000000000000000000000000000..2bdeb1ed5a590a17e69cbf3dc39c15002d5a154d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/IValidable.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.script;
+
+/**
+ * @author Izabela Adamczyk
+ */
+public interface IValidable
+{
+    boolean isValid();
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptEditForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptEditForm.java
index 3027fc9db0a7f44d35aeaabb6bf53e0814be7885..3446e28181094817b1a414daf493887d97132a01 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptEditForm.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptEditForm.java
@@ -46,19 +46,26 @@ public class ScriptEditForm extends AbstractScriptEditRegisterForm
 
     @Override
     protected void saveScript()
+    {
+        Script script = getScript();
+        viewContext.getService().updateScript(script, new ScriptEditCallback(viewContext));
+    }
+
+    @Override
+    public Script getScript()
     {
         Script script = new Script();
         script.setId(scriptId.getId());
         script.setDescription(descriptionField.getValue());
         script.setScript(scriptField.getValue());
         script.setName(nameField.getValue());
-        viewContext.getService().updateScript(script, new ScriptEditCallback(viewContext));
+        return script;
     }
 
     @Override
     protected void setValues()
     {
-        descriptionField.setValue(originalScript.getDescription());// FIXME: unescape?
+        descriptionField.setValue(originalScript.getDescription());
         scriptField.setValue(originalScript.getScript());
         nameField.setValue(originalScript.getName());
         String entityKind =
@@ -97,7 +104,6 @@ public class ScriptEditForm extends AbstractScriptEditRegisterForm
         @Override
         protected void process(final Void result)
         {
-            // originalScript.setModificationDate(result);
             updateOriginalValues();
             super.process(result);
         }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptExecutionFramework.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptExecutionFramework.java
new file mode 100644
index 0000000000000000000000000000000000000000..800d4e2f766e4c51f7236176e957e65bccb5f3ed
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptExecutionFramework.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.script;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.extjs.gxt.ui.client.Style.Scroll;
+import com.extjs.gxt.ui.client.event.ButtonEvent;
+import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
+import com.extjs.gxt.ui.client.event.SelectionChangedListener;
+import com.extjs.gxt.ui.client.event.SelectionListener;
+import com.extjs.gxt.ui.client.widget.Html;
+import com.extjs.gxt.ui.client.widget.button.Button;
+import com.extjs.gxt.ui.client.widget.form.AdapterField;
+import com.extjs.gxt.ui.client.widget.form.Field;
+import com.extjs.gxt.ui.client.widget.form.FieldSet;
+import com.extjs.gxt.ui.client.widget.form.FormPanel;
+import com.extjs.gxt.ui.client.widget.form.SimpleComboValue;
+import com.google.gwt.user.client.ui.Widget;
+
+import ch.systemsx.cisd.common.shared.basic.utils.StringUtils;
+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.IViewContext;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.SampleTypeDisplayID;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.renderer.LinkRenderer;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.AbstractRegistrationForm;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.ChosenEntitySetter;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.DataSetChooserField;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.ExperimentChooserField;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.ExperimentChooserField.ExperimentChooserFieldAdaptor;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.IChosenEntityListener;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.MaterialChooserField;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.SampleChooserField;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.field.SampleChooserField.SampleChooserFieldAdaptor;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.listener.OpenEntityDetailsTabClickListener;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.FieldUtil;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.MultilineHTML;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.WidgetUtils;
+import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWithPermId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DynamicPropertyEvaluationInfo;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
+
+/**
+ * @author Izabela Adamczyk
+ */
+public class ScriptExecutionFramework
+{
+
+    FormPanel panel;
+
+    private final IViewContext<ICommonClientServiceAsync> viewContext;
+
+    private final SampleChooserFieldAdaptor sampleChooser;
+
+    private final ExperimentChooserFieldAdaptor experimentChooser;
+
+    private final MaterialChooserField materialChooser;
+
+    private final DataSetChooserField datasetChooser;
+
+    private final FieldSet evaluationResultPanel;
+
+    private final EntityKindSelectionWidget entityKindChooser;
+
+    private final State state = new State();
+
+    private final AdapterField entityLink;
+
+    private final MultilineHTML html;
+
+    private final IValidable validable;
+
+    private static class State
+    {
+        private String script;
+
+        private IEntityInformationHolderWithPermId chosenEntity;
+
+        public String getScript()
+        {
+            return script;
+        }
+
+        public void setScript(String script)
+        {
+            this.script = script;
+        }
+
+        public IEntityInformationHolderWithPermId getChosenEntity()
+        {
+            return chosenEntity;
+        }
+
+        public void setChosenEntity(IEntityInformationHolderWithPermId chosenEntity)
+        {
+            this.chosenEntity = chosenEntity;
+        }
+
+    }
+
+    public ScriptExecutionFramework(IViewContext<ICommonClientServiceAsync> viewContext,
+            IValidable validable)
+    {
+        this.viewContext = viewContext;
+        this.validable = validable;
+        entityKindChooser = new EntityKindSelectionWidget(viewContext, null, true, false);
+        sampleChooser =
+                SampleChooserField.create(viewContext.getMessage(Dict.SAMPLE), true, null, true,
+                        false, true, viewContext.getCommonViewContext(),
+                        SampleTypeDisplayID.SCRIPT_EDITOR_SAMPLE_CHOOSER);
+        experimentChooser =
+                ExperimentChooserField.create(viewContext.getMessage(Dict.EXPERIMENT), true, null,
+                        viewContext);
+        materialChooser =
+                MaterialChooserField.create(viewContext.getMessage(Dict.MATERIAL), true, null,
+                        null, viewContext);
+        datasetChooser =
+                DataSetChooserField
+                        .create(viewContext.getMessage(Dict.DATA_SET), true, viewContext);
+        final Map<EntityKind, Field<?>> map =
+                createEntitySelectionMap(sampleChooser, experimentChooser, materialChooser,
+                        datasetChooser);
+        entityLink = createEntityLink();
+        html = new MultilineHTML("");
+        evaluationResultPanel = createResultField(html);
+        updateVisibleEntityChooser(map, entityKindChooser);
+        entityKindChooser
+                .addSelectionChangedListener(new SelectionChangedListener<SimpleComboValue<String>>()
+                    {
+                        @Override
+                        public void selectionChanged(
+                                SelectionChangedEvent<SimpleComboValue<String>> se)
+                        {
+                            updateVisibleEntityChooser(map, entityKindChooser);
+                        }
+                    });
+        setChosenEntityListener(sampleChooser.getChooserField(), state, entityLink);
+        setChosenEntityListener(experimentChooser.getChooserField(), state, entityLink);
+        setChosenEntityListener(materialChooser, state, entityLink);
+        setChosenEntityListener(datasetChooser, state, entityLink);
+
+        panel = createPanel();
+        panel.add(entityKindChooser);
+        panel.add(sampleChooser.getChooserField());
+        panel.add(experimentChooser.getChooserField());
+        panel.add(materialChooser);
+        panel.add(datasetChooser);
+        panel.add(entityLink);
+        panel.add(createButtonsField());
+        panel.add(evaluationResultPanel);
+        updateVisibleEntityLink(state, entityLink);
+    }
+
+    private static <T extends IEntityInformationHolderWithPermId> void setChosenEntityListener(
+            ChosenEntitySetter<T> setter, final State state, final Field<?> entityLink)
+    {
+        setter.addChosenEntityListener(new IChosenEntityListener<T>()
+            {
+                public void entityChosen(T entity)
+                {
+                    if (entity != null)
+                    {
+                        state.setChosenEntity(entity);
+                        updateVisibleEntityLink(state, entityLink);
+                    }
+                }
+            });
+    }
+
+    private AdapterField createButtonsField()
+    {
+        AdapterField field =
+                new AdapterField(WidgetUtils.inRow(createCalculateButton(), createSeparator(),
+                        createResetButton()));
+        field.setLabelSeparator("");
+        return field;
+    }
+
+    private Html createSeparator()
+    {
+        return new Html("&nbsp;");
+    }
+
+    private void reset()
+    {
+        panel.reset();
+        state.setChosenEntity(null);
+        updateVisibleEntityLink(state, entityLink);
+        html.setHTML("");
+        evaluationResultPanel.setVisible(false);
+    }
+
+    private Button createResetButton()
+    {
+        Button button = new Button(viewContext.getMessage(Dict.BUTTON_RESET));
+        button.addSelectionListener(new SelectionListener<ButtonEvent>()
+            {
+
+                @Override
+                public void componentSelected(ButtonEvent ce)
+                {
+                    reset();
+                }
+            });
+        return button;
+    }
+
+    private Button createCalculateButton()
+    {
+        Button refresh = new Button(viewContext.getMessage(Dict.BUTTON_EVALUATE));
+        refresh.addSelectionListener(new SelectionListener<ButtonEvent>()
+            {
+                @Override
+                public void componentSelected(ButtonEvent ce)
+                {
+                    boolean thisValid = panel.isValid();
+                    boolean dependantValid = validable.isValid();
+                    if (thisValid && dependantValid)
+                    {
+                        evaluationResultPanel.setVisible(true);
+                        evaluate();
+                    }
+                }
+            });
+        return refresh;
+    }
+
+    public FieldSet createResultField(MultilineHTML widget)
+    {
+        FieldSet fieldSet = new FieldSet();
+        fieldSet.setHeading(viewContext.getMessage(Dict.EVALUATION_RESULT));
+        fieldSet.add(widget);
+        fieldSet.setVisible(false);
+        return fieldSet;
+    }
+
+    private AdapterField createEntityLink()
+    {
+        AdapterField field =
+                new AdapterField(LinkRenderer.getLinkWidget(
+                        viewContext.getMessage(Dict.SHOW_DETAILS),
+                        new OpenEntityDetailsTabClickListener(null, viewContext)
+                            {
+                                @Override
+                                protected IEntityInformationHolderWithPermId getEntity()
+                                {
+                                    return state.getChosenEntity();
+                                }
+                            }));
+        field.setFieldLabel(viewContext.getMessage(Dict.ENTITY_DETAILS));
+        return field;
+
+    }
+
+    public Widget getWidget()
+    {
+        FieldSet set = new FieldSet();
+        set.setHeading(viewContext.getMessage(Dict.SCRIPT_TESTER));
+        set.add(panel);
+        return set;
+    }
+
+    public void update(String script)
+    {
+        state.setScript(script);
+    }
+
+    private void evaluate()
+    {
+        if (StringUtils.isBlank(sampleChooser.getValue()) == false)
+        {
+            evaluate(EntityKind.SAMPLE, sampleChooser.getValue(), state.getScript());
+        }
+        if (experimentChooser.tryToGetValue() != null
+                && StringUtils.isBlank(experimentChooser.tryToGetValue().getIdentifier()) == false)
+        {
+            evaluate(EntityKind.EXPERIMENT, experimentChooser.tryToGetValue().getIdentifier(),
+                    state.getScript());
+        }
+        if (StringUtils.isBlank(materialChooser.getValue()) == false)
+        {
+            evaluate(EntityKind.MATERIAL, materialChooser.getValue(), state.getScript());
+        }
+        if (StringUtils.isBlank(datasetChooser.getValue()) == false)
+        {
+            evaluate(EntityKind.DATA_SET, datasetChooser.getValue(), state.getScript());
+        }
+    }
+
+    private void evaluate(EntityKind kind, String entity, String script)
+    {
+        if (entity == null)
+        {
+            return;
+        }
+        updateEvaluationResultField(viewContext.getMessage(Dict.EVALUATION_IN_PROGRESS));
+        viewContext.getCommonService().evaluate(
+                new DynamicPropertyEvaluationInfo(kind, entity, script),
+                new AbstractAsyncCallback<String>(viewContext)
+                    {
+
+                        @Override
+                        protected void process(String result)
+                        {
+                            updateEvaluationResultField(result);
+                        }
+
+                        @Override
+                        public void finishOnFailure(Throwable caught)
+                        {
+                            updateEvaluationResultField(caught.getMessage());
+                        }
+                    });
+    }
+
+    private void updateEvaluationResultField(String result)
+    {
+        html.setHTML(result);
+    }
+
+    private static void updateVisibleEntityLink(State state, Field<?> entityLink)
+    {
+        FieldUtil.setVisibility(state.getChosenEntity() != null, entityLink);
+    }
+
+    private static void updateVisibleEntityChooser(Map<EntityKind, Field<?>> map,
+            EntityKindSelectionWidget entityKindChooser)
+    {
+        for (Field<?> w : map.values())
+        {
+            EntityKind kind = entityKindChooser.tryGetEntityKind();
+            FieldUtil.setVisibility(kind != null && w == map.get(kind), w);
+        }
+    }
+
+    private static FormPanel createPanel()
+    {
+        FormPanel p = new FormPanel();
+        p.setHeaderVisible(false);
+        p.setBodyBorder(false);
+        p.setBorders(false);
+        p.setScrollMode(Scroll.AUTO);
+        p.setWidth(AbstractRegistrationForm.DEFAULT_LABEL_WIDTH
+                + AbstractRegistrationForm.DEFAULT_FIELD_WIDTH / 2
+                + AbstractRegistrationForm.PANEL_MARGIN);
+        p.setLabelWidth(AbstractRegistrationForm.DEFAULT_LABEL_WIDTH);
+        p.setFieldWidth(AbstractRegistrationForm.DEFAULT_FIELD_WIDTH / 2);
+        return p;
+    }
+
+    private static Map<EntityKind, Field<?>> createEntitySelectionMap(
+            SampleChooserFieldAdaptor sampleChooser,
+            ExperimentChooserFieldAdaptor experimentChooser, MaterialChooserField materialChooser,
+            DataSetChooserField datasetChooser)
+    {
+        Map<EntityKind, Field<?>> m = new HashMap<EntityKind, Field<?>>();
+        m.put(EntityKind.SAMPLE, sampleChooser.getChooserField());
+        m.put(EntityKind.EXPERIMENT, experimentChooser.getChooserField());
+        m.put(EntityKind.MATERIAL, materialChooser);
+        m.put(EntityKind.DATA_SET, datasetChooser);
+        return m;
+    }
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptRegistrationForm.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptRegistrationForm.java
index d9a9bf82b73eea886661ed2b29c74b2a1297f79b..2517faf4e7ce390f46ae29fcb938c0f839d75434 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptRegistrationForm.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/script/ScriptRegistrationForm.java
@@ -17,7 +17,6 @@
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.script;
 
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAsync;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.GenericConstants;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.AbstractRegistrationForm;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind;
@@ -43,20 +42,21 @@ public class ScriptRegistrationForm extends AbstractScriptEditRegisterForm
 
     @Override
     protected void saveScript()
+    {
+        Script newScript = getScript();
+        viewContext.getService().registerScript(newScript,
+                new ScriptRegistrationCallback(viewContext, newScript));
+    }
+
+    @Override
+    public Script getScript()
     {
         Script newScript = new Script();
         newScript.setDescription(descriptionField.getValue());
         newScript.setName(nameField.getValue());
         newScript.setScript(scriptField.getValue());
-        EntityKind kind = null;
-        String selectedEntityKind = entityKindField.getValue().getValue();
-        if (selectedEntityKind.equals(GenericConstants.ALL_ENTITY_KINDS) == false)
-        {
-            kind = EntityKind.valueOf(selectedEntityKind);
-        }
-        newScript.setEntityKind(kind);
-        viewContext.getService().registerScript(newScript,
-                new ScriptRegistrationCallback(viewContext, newScript));
+        newScript.setEntityKind(entityKindField.tryGetEntityKind());
+        return newScript;
     }
 
     private final class ScriptRegistrationCallback extends
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/MultilineHTML.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/MultilineHTML.java
index 85cb6c3f72f8bdc38e68daa1dad54ff5125669cb..53485ee26eb712dacd9dd38d054176887d0cf254 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/MultilineHTML.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/widget/MultilineHTML.java
@@ -44,6 +44,12 @@ public final class MultilineHTML extends HTML
         super(preserveWhitespace(html));
     }
 
+    @Override
+    public void setHTML(String html)
+    {
+        super.setHTML(preserveWhitespace(html));
+    }
+
     private static final String BR = DOM.toString(DOM.createElement("br"));
 
     private static String preserveWhitespace(String html)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/util/WidgetUtils.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/util/WidgetUtils.java
index 77d8ba13754950550ac0cf6d9f310a1f63efa54d..a600287a040768d8eb6b89f61f69152cd938f20b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/util/WidgetUtils.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/util/WidgetUtils.java
@@ -16,13 +16,20 @@
 
 package ch.systemsx.cisd.openbis.generic.client.web.client.application.util;
 
+import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
 import com.extjs.gxt.ui.client.Style.Orientation;
+import com.extjs.gxt.ui.client.Style.Scroll;
+import com.extjs.gxt.ui.client.Style.VerticalAlignment;
 import com.extjs.gxt.ui.client.event.BaseEvent;
 import com.extjs.gxt.ui.client.event.Events;
 import com.extjs.gxt.ui.client.event.Listener;
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
 import com.extjs.gxt.ui.client.widget.form.Radio;
 import com.extjs.gxt.ui.client.widget.form.RadioGroup;
+import com.extjs.gxt.ui.client.widget.layout.TableData;
+import com.extjs.gxt.ui.client.widget.layout.TableLayout;
 import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.user.client.ui.Widget;
 
 /**
  * Utility methods for widgets.
@@ -98,4 +105,22 @@ public class WidgetUtils
         return result;
     }
 
+    public static LayoutContainer inRow(Widget... containers)
+    {
+        return asTable(containers.length, containers);
+    }
+
+    public static LayoutContainer asTable(int columns, Widget... containers)
+    {
+        LayoutContainer container = new LayoutContainer();
+        container.setLayout(new TableLayout(columns));
+        container.setBorders(false);
+        container.setScrollMode(Scroll.AUTO);
+        for (Widget w : containers)
+        {
+            container.add(w, new TableData(HorizontalAlignment.LEFT, VerticalAlignment.TOP));
+        }
+        return container;
+    }
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
index 9a038e63373b65421f465f4afaeeb45712abd8a8..fe24a5258c6a838e72f568c334b976d2072e04db 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/CommonClientService.java
@@ -97,6 +97,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DynamicPropertyEvaluationInfo;
 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.EntityTypePropertyType;
@@ -2598,4 +2599,17 @@ public final class CommonClientService extends AbstractClientService implements
         }
     }
 
+    public String evaluate(DynamicPropertyEvaluationInfo info)
+            throws ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException
+    {
+        try
+        {
+            final String sessionToken = getSessionToken();
+            return commonServer.evaluate(sessionToken, info);
+        } catch (final ch.systemsx.cisd.common.exceptions.UserFailureException e)
+        {
+            throw UserFailureExceptionTranslator.translate(e);
+        }
+    }
+
 }
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 1f3be2df8d235b043edef01d1f35ed824366fd5e..353e14e8d726bea71e64b7e510324a88eff75328 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
@@ -70,6 +70,9 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IFileFormatTypeDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IHibernateSearchDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IRoleAssignmentDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.HibernateSearchDataProvider;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.dynamic_property.DynamicPropertyEvaluator;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.dynamic_property.calculator.DynamicPropertyCalculator;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.dynamic_property.calculator.EntityAdaptorFactory;
 import ch.systemsx.cisd.openbis.generic.server.plugin.IDataSetTypeSlaveServerPlugin;
 import ch.systemsx.cisd.openbis.generic.server.util.GroupIdentifierHelper;
 import ch.systemsx.cisd.openbis.generic.shared.basic.BasicEntityInformationHolder;
@@ -89,6 +92,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DeletedDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DynamicPropertyEvaluationInfo;
 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.Experiment;
@@ -152,6 +156,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.FileFormatTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GridCustomFilterPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.GroupPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityInformationHolderDTO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityInformationWithPropertiesHolder;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.NewRoleAssignment;
 import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
@@ -168,7 +173,9 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyTermWithStats;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory;
 import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier;
 import ch.systemsx.cisd.openbis.generic.shared.translator.AttachmentTranslator;
 import ch.systemsx.cisd.openbis.generic.shared.translator.AuthorizationGroupTranslator;
@@ -2044,4 +2051,50 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt
         return ScriptTranslator.translate(script);
     }
 
+    public String evaluate(String sessionToken, DynamicPropertyEvaluationInfo info)
+    {
+        Session session = getSession(sessionToken);
+        DynamicPropertyCalculator calculator = DynamicPropertyCalculator.create(info.getScript());
+        calculator.setEntity(EntityAdaptorFactory.create(getEntity(info, session),
+                new DynamicPropertyEvaluator()));
+        return calculator.evalAsString();
+    }
+
+    public IEntityInformationWithPropertiesHolder getEntity(DynamicPropertyEvaluationInfo info,
+            Session session)
+    {
+        IEntityInformationWithPropertiesHolder entity = null;
+        switch (info.getEntityKind())
+        {
+            case DATA_SET:
+                IExternalDataBO bo = businessObjectFactory.createExternalDataBO(session);
+                bo.loadByCode(info.getEntityIdentifier());
+                entity = bo.getExternalData();
+                break;
+            case EXPERIMENT:
+                IExperimentBO expBO = businessObjectFactory.createExperimentBO(session);
+                ExperimentIdentifier expIdentifier =
+                        new ExperimentIdentifierFactory(info.getEntityIdentifier())
+                                .createIdentifier();
+                entity = expBO.tryFindByExperimentIdentifier(expIdentifier);
+                break;
+            case SAMPLE:
+                ISampleBO sampleBO = businessObjectFactory.createSampleBO(session);
+                sampleBO.tryToLoadBySampleIdentifier(SampleIdentifierFactory.parse(info
+                        .getEntityIdentifier()));
+                entity = sampleBO.getSample();
+                break;
+            case MATERIAL:
+                entity =
+                        getDAOFactory().getMaterialDAO().tryFindMaterial(
+                                MaterialIdentifier.tryParseIdentifier(info.getEntityIdentifier()));
+                break;
+        }
+        if (entity == null)
+        {
+            throw new UserFailureException(String.format("%s '%s' not found", info.getEntityKind()
+                    .getDescription(), info.getEntityIdentifier()));
+        }
+        return entity;
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
index bdf87d86ab5a20fdb01892ebd38701deb7464548..bc8bb5a096534c6a4d3ac889bb87e10a261c5f33 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java
@@ -39,6 +39,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DynamicPropertyEvaluationInfo;
 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.Experiment;
@@ -920,4 +921,11 @@ final class CommonServerLogger extends AbstractServerLogger implements ICommonSe
         logAccess(sessionToken, "getScriptInfo", "SCRIPT(%s)", scriptId);
         return null;
     }
+
+    public String evaluate(String sessionToken, DynamicPropertyEvaluationInfo info)
+    {
+        logAccess(sessionToken, "evaluate", "%s(%s)", info.getEntityKind().name(),
+                info.getEntityIdentifier());
+        return null;
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
index c696c72ecc1cae391ee0f0579d45e746d57e322a..3409f7cf1fda2af82480e32714cb181fbcc3be79 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ICommonServer.java
@@ -63,6 +63,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind.ObjectKind;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DynamicPropertyEvaluationInfo;
 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.Experiment;
@@ -1163,4 +1164,11 @@ public interface ICommonServer extends IServer
     @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER)
     public Script getScriptInfo(String sessionToken, TechId scriptId);
 
+    /**
+     * Evaluates given script for selected entity.
+     */
+    @Transactional(readOnly = true)
+    @RolesAllowed(RoleWithHierarchy.INSTANCE_ADMIN)
+    public String evaluate(String sessionToken, DynamicPropertyEvaluationInfo info);
+
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DynamicPropertyEvaluationInfo.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DynamicPropertyEvaluationInfo.java
new file mode 100644
index 0000000000000000000000000000000000000000..89d025f5d15f6dd0dfa38c0462e09618d5a5528c
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/DynamicPropertyEvaluationInfo.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.generic.shared.basic.dto;
+
+import java.io.Serializable;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+/**
+ * @author Izabela Adamczyk
+ */
+public class DynamicPropertyEvaluationInfo implements IsSerializable, Serializable
+{
+    private static final long serialVersionUID = ServiceVersionHolder.VERSION;
+
+    private EntityKind entityKind;
+
+    private String script;
+
+    private String entityIdentifier;
+
+    public DynamicPropertyEvaluationInfo()
+    {
+    }
+
+    public DynamicPropertyEvaluationInfo(EntityKind entityKind, String entityIdentifier,
+            String script)
+    {
+        this.entityKind = entityKind;
+        this.entityIdentifier = entityIdentifier;
+        this.script = script;
+    }
+
+    public EntityKind getEntityKind()
+    {
+        return entityKind;
+    }
+
+    public void setEntityKind(EntityKind entityKind)
+    {
+        this.entityKind = entityKind;
+    }
+
+    public String getScript()
+    {
+        return script;
+    }
+
+    public void setScript(String script)
+    {
+        this.script = script;
+    }
+
+    public String getEntityIdentifier()
+    {
+        return entityIdentifier;
+    }
+
+    public void setEntityIdentifier(String entityIdentifier)
+    {
+        this.entityIdentifier = entityIdentifier;
+    }
+
+}
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
index 7c83dc625da2b2d17c4795bdd4a4c30932afcf60..cd9a8c4b9757c1893a18efc00fbf08c02cc006db 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/public/common-dictionary.js
@@ -92,6 +92,7 @@ var common = {
   button_upload_data_via_cifex: "Upload Data",
   button_process: "Process",
   button_top: "Files",
+  button_evaluate: "Evaluate",
   
   tooltip_refresh_disabled: "To activate select appropriate criteria first.",
   tooltip_refresh_enabled: "Load or update the table.",
@@ -694,6 +695,13 @@ title_choose_script: "Choose a Script",
 script_browser: "Scripts",
 ADMINISTRATION_MENU_SCRIPTS: "Scripts",
 script_registration: "Script Registration",
+evaluation_result: "Evaluation Result",
+script_tester: "Script Tester",
+entity_details: "Details",
+show_details: "Show",
+evaluation_in_progress: "Evaluation in progress...",
+warning_no_script_title: "Empty script",
+warning_no_script_message: "No script provided",
  
  // LAST LINE: KEEP IT AT THE END
   lastline: "" // we need a line without a comma