diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/AbstractEntityPickerPanel.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/AbstractEntityPickerPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..c09bee169b1fafb5e59b3ff09d5dbcaa37b3c7da
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/AbstractEntityPickerPanel.java
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+/*
+ * 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.dss.client.api.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Insets;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusListener;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import ch.systemsx.cisd.openbis.dss.client.api.v1.IOpenbisServiceFacade;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment;
+
+/**
+ * @author Pawel Glyzewski
+ */
+public abstract class AbstractEntityPickerPanel extends JPanel implements ActionListener
+{
+
+    private static final long serialVersionUID = 1L;
+
+    static class JTextFieldFireActionPerformedExposed extends JTextField
+    {
+        private static final long serialVersionUID = -7656053161479466883L;
+
+        @Override
+        public void fireActionPerformed()
+        {
+            super.fireActionPerformed();
+        }
+    }
+
+    protected final JTextFieldFireActionPerformedExposed textField =
+            new JTextFieldFireActionPerformedExposed();
+
+    private final JButton button = new JButton("...");
+
+    public AbstractEntityPickerPanel(final JFrame mainWindow, List<Experiment> experiments,
+            IOpenbisServiceFacade openbisService)
+    {
+        super(new BorderLayout());
+
+        button.setMargin(new Insets(button.getMargin().top, 2, button.getMargin().bottom, 2));
+        button.addActionListener(this);
+        button.setToolTipText(getButtonToolTipText());
+
+        add(textField, BorderLayout.CENTER);
+        add(button, BorderLayout.EAST);
+    }
+
+    public String getText()
+    {
+        return textField.getText();
+    }
+
+    public void setText(String text)
+    {
+        textField.setText(text);
+    }
+
+    public void addActionListener(ActionListener actionListener)
+    {
+        textField.addActionListener(actionListener);
+    }
+
+    @Override
+    public void addFocusListener(FocusListener focusListener)
+    {
+        textField.addFocusListener(focusListener);
+        button.addFocusListener(focusListener);
+    }
+
+    @Override
+    public void setEnabled(boolean enabled)
+    {
+        textField.setEditable(enabled);
+        textField.setEnabled(enabled);
+        button.setEnabled(enabled);
+    }
+
+    @Override
+    public void setToolTipText(String tooltip)
+    {
+        textField.setToolTipText(tooltip);
+    }
+
+    protected abstract String getButtonToolTipText();
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetMetadataPanel.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetMetadataPanel.java
index dd378dbf9a271b4229988a8481779e614b49e025..86713efaf9851d8a1bebd22506d4993cae481200 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetMetadataPanel.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetMetadataPanel.java
@@ -46,7 +46,6 @@ import javax.swing.JComponent;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
-import javax.swing.JTextField;
 
 import ch.systemsx.cisd.openbis.dss.client.api.gui.DataSetPropertiesPanel.Observer;
 import ch.systemsx.cisd.openbis.dss.client.api.gui.DataSetUploadClientModel.NewDataSetInfo;
@@ -142,7 +141,7 @@ public class DataSetMetadataPanel extends JPanel implements Observer
 
     private final SamplePickerPanel samplePanel;
 
-    private final JTextField dataSetIdText;
+    private final DataSetPickerPanel dataSetPanel;
 
     private final ExperimentPickerPanel experimentPicker;
 
@@ -187,15 +186,19 @@ public class DataSetMetadataPanel extends JPanel implements Observer
         samplePanel =
                 new SamplePickerPanel(mainWindow, clientModel.getExperiments(),
                         clientModel.getOpenBISService());
-        dataSetIdText = new JTextField();
-        experimentPicker = new ExperimentPickerPanel(mainWindow, clientModel.getExperiments());
+        dataSetPanel =
+                new DataSetPickerPanel(mainWindow, clientModel.getExperiments(),
+                        clientModel.getOpenBISService());
+        experimentPicker =
+                new ExperimentPickerPanel(mainWindow, clientModel.getExperiments(),
+                        clientModel.getOpenBISService());
 
         ownerIdPanel = new JPanel(new CardLayout());
         ownerComboBox = new JComboBox(DataSetOwnerType.values());
 
         ownerIdPanel.add(experimentPicker, DataSetOwnerType.EXPERIMENT.toString());
         ownerIdPanel.add(samplePanel, DataSetOwnerType.SAMPLE.toString());
-        ownerIdPanel.add(dataSetIdText, DataSetOwnerType.DATA_SET.toString());
+        ownerIdPanel.add(dataSetPanel, DataSetOwnerType.DATA_SET.toString());
 
         dataSetTypeComboBox = new JComboBox();
         dataSetTypePanel = new JPanel();
@@ -245,7 +248,7 @@ public class DataSetMetadataPanel extends JPanel implements Observer
                     samplePanel.setText(builder.getDataSetOwnerIdentifier());
                     break;
                 case DATA_SET:
-                    dataSetIdText.setText(builder.getDataSetOwnerIdentifier());
+                    dataSetPanel.setText(builder.getDataSetOwnerIdentifier());
                     break;
             }
         }
@@ -286,7 +289,7 @@ public class DataSetMetadataPanel extends JPanel implements Observer
     private ArrayList<JComponent> getAllEditableWidgets()
     {
         ArrayList<JComponent> editableWidgets = new ArrayList<JComponent>();
-        editableWidgets.add(dataSetIdText);
+        editableWidgets.add(dataSetPanel);
         editableWidgets.add(samplePanel);
         editableWidgets.add(experimentPicker);
         editableWidgets.add(dataSetFileButton);
@@ -382,6 +385,7 @@ public class DataSetMetadataPanel extends JPanel implements Observer
         ownerIdLabel.setPreferredSize(new Dimension(LABEL_WIDTH, BUTTON_HEIGHT));
 
         samplePanel.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT));
+        samplePanel.setToolTipText("Sample identifier");
         samplePanel.addActionListener(new ActionListener()
             {
 
@@ -406,6 +410,7 @@ public class DataSetMetadataPanel extends JPanel implements Observer
             });
 
         experimentPicker.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT));
+        experimentPicker.setToolTipText("Experiment identifier");
         experimentPicker.addActionListener(new ActionListener()
             {
                 public void actionPerformed(ActionEvent e)
@@ -427,21 +432,23 @@ public class DataSetMetadataPanel extends JPanel implements Observer
                 }
             });
 
-        dataSetIdText.addActionListener(new ActionListener()
+        dataSetPanel.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT));
+        dataSetPanel.setToolTipText("Parent Data Set code");
+        dataSetPanel.addActionListener(new ActionListener()
             {
 
                 public void actionPerformed(ActionEvent e)
                 {
-                    setOwnerId(dataSetIdText.getText());
+                    setOwnerId(dataSetPanel.getText());
                 }
 
             });
-        dataSetIdText.addFocusListener(new FocusListener()
+        dataSetPanel.addFocusListener(new FocusListener()
             {
 
                 public void focusLost(FocusEvent e)
                 {
-                    setOwnerId(dataSetIdText.getText());
+                    setOwnerId(dataSetPanel.getText());
                 }
 
                 public void focusGained(FocusEvent e)
@@ -670,7 +677,7 @@ public class DataSetMetadataPanel extends JPanel implements Observer
             case SAMPLE:
                 return samplePanel.getText();
             case DATA_SET:
-                return dataSetIdText.getText();
+                return dataSetPanel.getText();
         }
 
         return null;
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPickerDialog.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPickerDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..5357163358a3ab2b8c93daaf4e362cc0a0a3fea9
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPickerDialog.java
@@ -0,0 +1,277 @@
+/*
+ * 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.dss.client.api.gui;
+
+import java.awt.Point;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Collections;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import javax.swing.JTree;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.TreeExpansionEvent;
+import javax.swing.event.TreeWillExpandListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.ExpandVetoException;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
+
+import ch.systemsx.cisd.openbis.dss.client.api.gui.tree.FilterableMutableTreeNode;
+import ch.systemsx.cisd.openbis.dss.client.api.v1.DataSet;
+import ch.systemsx.cisd.openbis.dss.client.api.v1.IOpenbisServiceFacade;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Sample;
+
+/**
+ * @author Pawel Glyzewski
+ */
+public class DataSetPickerDialog extends JDialog implements TreeWillExpandListener
+{
+    private static final long serialVersionUID = 1L;
+
+    private final JTree tree;
+
+    private final JTextField filterField;
+
+    private final JFrame mainWindow;
+
+    private final JOptionPane optionPane;
+
+    private final IOpenbisServiceFacade openbisService;
+
+    private final Timer scheduler = new Timer();
+
+    /**
+     * @param mainWindow
+     * @param experiments
+     * @param openbisService
+     */
+    public DataSetPickerDialog(JFrame mainWindow, List<Experiment> experiments,
+            final IOpenbisServiceFacade openbisService)
+    {
+        super(mainWindow, "Pick a data set", true);
+
+        this.mainWindow = mainWindow;
+        this.openbisService = openbisService;
+
+        FilterableMutableTreeNode top = new FilterableMutableTreeNode("Experiments");
+        createNodes(top, experiments);
+        tree = new JTree(top);
+        tree.addTreeWillExpandListener(this);
+        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+
+        filterField = createFilterField(top, tree);
+
+        optionPane = createOptionPane(filterField, tree, this);
+        this.setContentPane(optionPane);
+    }
+
+    private static JOptionPane createOptionPane(JTextField filterField, final JTree tree,
+            final JDialog parent)
+    {
+        final JScrollPane scrollPane = new JScrollPane(tree);
+
+        Object[] objects = new Object[]
+            { "Filter experiments: ", filterField, "Select Sample:", scrollPane };
+        final JOptionPane optionPane =
+                new JOptionPane(objects, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
+        optionPane.addPropertyChangeListener(new PropertyChangeListener()
+            {
+                public void propertyChange(PropertyChangeEvent evt)
+                {
+                    if (evt.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)
+                            && evt.getNewValue() != null)
+                    {
+                        if (((Integer) evt.getNewValue()).intValue() == JOptionPane.OK_OPTION
+                                && tree.getSelectionPath() == null)
+                        {
+                            JOptionPane.showMessageDialog(parent, "Sample needs to be selected!",
+                                    "No sample selected!", JOptionPane.WARNING_MESSAGE);
+                            optionPane.setValue(optionPane.getInitialValue());
+                        } else if (((Integer) evt.getNewValue()).intValue() == JOptionPane.OK_OPTION
+                                && tree.getSelectionPath().getPath().length < 3)
+                        {
+                            JOptionPane.showMessageDialog(parent,
+                                    "Sample should be selected, not experiment!",
+                                    "No sample selected!", JOptionPane.WARNING_MESSAGE);
+                            optionPane.setValue(optionPane.getInitialValue());
+                        } else
+                        {
+                            parent.setVisible(false);
+                        }
+                    }
+                }
+            });
+
+        return optionPane;
+    }
+
+    private static void createNodes(FilterableMutableTreeNode top, List<Experiment> experiments)
+    {
+        for (Experiment experiment : experiments)
+        {
+            DefaultMutableTreeNode category =
+                    new DefaultMutableTreeNode(experiment.getIdentifier(), true);
+            category.add(new DefaultMutableTreeNode("dummy child"));
+            top.add(category);
+        }
+    }
+
+    private static JTextField createFilterField(final FilterableMutableTreeNode treeNode,
+            final JTree tree)
+    {
+        final JTextField filterField = new JTextField();
+        filterField.setEditable(true);
+        filterField.getDocument().addDocumentListener(new DocumentListener()
+            {
+                public void removeUpdate(DocumentEvent e)
+                {
+                    treeNode.filter(filterField.getText());
+                    ((DefaultTreeModel) tree.getModel()).reload();
+                }
+
+                public void insertUpdate(DocumentEvent e)
+                {
+                    treeNode.filter(filterField.getText());
+                    ((DefaultTreeModel) tree.getModel()).reload();
+                }
+
+                public void changedUpdate(DocumentEvent e)
+                {
+                    treeNode.filter(filterField.getText());
+                    ((DefaultTreeModel) tree.getModel()).reload();
+                }
+            });
+
+        return filterField;
+    }
+
+    public String pickDataSet()
+    {
+        this.pack();
+
+        int height = this.getHeight() > 500 ? 500 : this.getHeight();
+        int width = this.getWidth() > 600 ? 600 : this.getWidth();
+        this.setSize(width, height);
+
+        Point mwLocation = mainWindow.getLocationOnScreen();
+        int x = mwLocation.x + (mainWindow.getWidth() / 2) - (this.getWidth() / 2);
+        int y = mwLocation.y + (mainWindow.getHeight() / 2) - (this.getHeight() / 2);
+
+        this.setLocation(x > 0 ? x : 0, y > 0 ? y : 0);
+
+        this.setVisible(true);
+
+        Object value = optionPane.getValue();
+        optionPane.setValue(optionPane.getInitialValue());
+        if (value == null || ((Integer) value).intValue() == JOptionPane.CANCEL_OPTION)
+        {
+            return null;
+        } else
+        {
+            return tree.getSelectionPath().getLastPathComponent().toString();
+        }
+    }
+
+    public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException
+    {
+        final DefaultMutableTreeNode node =
+                (DefaultMutableTreeNode) event.getPath().getLastPathComponent();
+        if (node.toString().equals("Data Sets"))
+        {
+            return;
+        }
+        node.removeAllChildren();
+
+        if (node.getPath().length == 3) // get datasets for samples
+        {
+            List<DataSet> dataSets =
+                    openbisService.listDataSetsForSamples(Collections.singletonList(event.getPath()
+                            .getLastPathComponent().toString()));
+
+            for (DataSet dataSet : dataSets)
+            {
+                node.add(new DefaultMutableTreeNode(dataSet.getCode()));
+            }
+        } else
+        // get datasets and samples for experiment
+        {
+            // if top level, then finish
+            if (((TreeNode) event.getPath().getLastPathComponent()).getParent() == null)
+            {
+                return;
+            }
+
+            List<Sample> samples =
+                    openbisService.listSamplesForExperiments(Collections.singletonList(event
+                            .getPath().getLastPathComponent().toString()));
+
+            List<DataSet> dataSets =
+                    openbisService.listDataSetsForExperiments(Collections.singletonList(event
+                            .getPath().getLastPathComponent().toString()));
+
+            if (dataSets.size() > 0)
+            {
+                DefaultMutableTreeNode dataSetsNode = new DefaultMutableTreeNode("Data Sets");
+                node.add(dataSetsNode);
+                for (DataSet dataSet : dataSets)
+                {
+                    dataSetsNode.add(new DefaultMutableTreeNode(dataSet.getCode()));
+                }
+            }
+
+            for (Sample s : samples)
+            {
+                DefaultMutableTreeNode sampleNode = new DefaultMutableTreeNode(s.getIdentifier());
+                sampleNode.add(new DefaultMutableTreeNode("dummy child"));
+                node.add(sampleNode);
+            }
+        }
+
+        if (node.getChildCount() == 0)
+        {
+            scheduler.schedule(new TimerTask()
+                {
+                    @Override
+                    public void run()
+                    {
+                        tree.collapsePath(new TreePath(node.getPath()));
+                    }
+                }, 1500l);
+        }
+    }
+
+    public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException
+    {
+        DefaultMutableTreeNode node =
+                (DefaultMutableTreeNode) event.getPath().getLastPathComponent();
+
+        node.removeAllChildren();
+        node.add(new DefaultMutableTreeNode("dummy child"));
+    }
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPickerPanel.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPickerPanel.java
new file mode 100644
index 0000000000000000000000000000000000000000..b4d4217292e2b15ce0ccceb2bfae6ce8a5e5c399
--- /dev/null
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetPickerPanel.java
@@ -0,0 +1,59 @@
+/*
+ * 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.dss.client.api.gui;
+
+import java.awt.event.ActionEvent;
+import java.util.List;
+
+import javax.swing.JFrame;
+
+import ch.systemsx.cisd.openbis.dss.client.api.v1.IOpenbisServiceFacade;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment;
+
+/**
+ * @author Pawel Glyzewski
+ */
+public class DataSetPickerPanel extends AbstractEntityPickerPanel
+{
+    private static final long serialVersionUID = 1L;
+
+    private final DataSetPickerDialog dialog;
+
+    public DataSetPickerPanel(final JFrame mainWindow, List<Experiment> experiments,
+            IOpenbisServiceFacade openbisService)
+    {
+        super(mainWindow, experiments, openbisService);
+
+        dialog = new DataSetPickerDialog(mainWindow, experiments, openbisService);
+    }
+
+    public void actionPerformed(ActionEvent e)
+    {
+        String dataSetId = dialog.pickDataSet();
+        if (dataSetId != null)
+        {
+            textField.setText(dataSetId);
+            textField.fireActionPerformed();
+        }
+    }
+
+    @Override
+    protected String getButtonToolTipText()
+    {
+        return "Pick a Data Set";
+    }
+}
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/ExperimentPickerPanel.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/ExperimentPickerPanel.java
index 91ed5dd05a99707789987d2f05e4976dae583e75..f9733c211ccc4faf01aa7a5fb03dbbf303e598d8 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/ExperimentPickerPanel.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/ExperimentPickerPanel.java
@@ -16,97 +16,44 @@
 
 package ch.systemsx.cisd.openbis.dss.client.api.gui;
 
-import java.awt.BorderLayout;
-import java.awt.Insets;
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.FocusListener;
 import java.util.List;
 
-import javax.swing.JButton;
 import javax.swing.JFrame;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
 
+import ch.systemsx.cisd.openbis.dss.client.api.v1.IOpenbisServiceFacade;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment;
 
 /**
  * @author Pawel Glyzewski
  */
-public class ExperimentPickerPanel extends JPanel
+public class ExperimentPickerPanel extends AbstractEntityPickerPanel
 {
-    private static final long serialVersionUID = -8093481985680332715L;
-
-    private static class JTextFieldFireActionPerformedExposed extends JTextField
-    {
-        private static final long serialVersionUID = -7656053161479466883L;
-
-        @Override
-        public void fireActionPerformed()
-        {
-            super.fireActionPerformed();
-        }
-    }
-
-    private final JTextFieldFireActionPerformedExposed textField =
-            new JTextFieldFireActionPerformedExposed();
-
-    private final JButton button = new JButton("...");
+    private static final long serialVersionUID = 1L;
 
     private final ExperimentPickerDialog dialog;
 
-    public ExperimentPickerPanel(final JFrame mainWindow, final List<Experiment> experiments)
+    public ExperimentPickerPanel(final JFrame mainWindow, final List<Experiment> experiments,
+            IOpenbisServiceFacade openbisServiceFacade)
     {
-        super(new BorderLayout());
+        super(mainWindow, experiments, openbisServiceFacade);
 
         dialog = new ExperimentPickerDialog(mainWindow, experiments);
-
-        button.setMargin(new Insets(button.getMargin().top, 2, button.getMargin().bottom, 2));
-
-        button.addActionListener(new ActionListener()
-            {
-                public void actionPerformed(ActionEvent e)
-                {
-                    String experimentId = dialog.pickExperiment();
-                    if (experimentId != null)
-                    {
-                        textField.setText(experimentId);
-                        textField.fireActionPerformed();
-                    }
-                }
-            });
-
-        add(textField, BorderLayout.CENTER);
-        add(button, BorderLayout.EAST);
     }
 
-    public String getText()
+    public void actionPerformed(ActionEvent e)
     {
-        return textField.getText();
-    }
-
-    public void setText(String text)
-    {
-        textField.setText(text);
-    }
-
-    public void addActionListener(ActionListener actionListener)
-    {
-        textField.addActionListener(actionListener);
-    }
-
-    @Override
-    public void addFocusListener(FocusListener focusListener)
-    {
-        textField.addFocusListener(focusListener);
-        button.addFocusListener(focusListener);
+        String experimentId = dialog.pickExperiment();
+        if (experimentId != null)
+        {
+            textField.setText(experimentId);
+            textField.fireActionPerformed();
+        }
     }
 
     @Override
-    public void setEnabled(boolean enabled)
+    protected String getButtonToolTipText()
     {
-        textField.setEditable(enabled);
-        textField.setEnabled(enabled);
-        button.setEnabled(enabled);
+        return "Pick an Experiment";
     }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/SamplePickerDialog.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/SamplePickerDialog.java
index 862ef6cca1954e9fbbcdbe9efb442a14eacae3dc..9e2cc16841818f76631397a06816aeeaa1ee6aa5 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/SamplePickerDialog.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/SamplePickerDialog.java
@@ -106,7 +106,6 @@ public class SamplePickerDialog extends JDialog implements TreeWillExpandListene
                     if (evt.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)
                             && evt.getNewValue() != null)
                     {
-                        System.out.println(tree.getSelectionPath().getPath().length);
                         if (((Integer) evt.getNewValue()).intValue() == JOptionPane.OK_OPTION
                                 && tree.getSelectionPath() == null)
                         {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/SamplePickerPanel.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/SamplePickerPanel.java
index c3093e8bec0a0dce0fe6730525c22a35033b3084..3a44f109a2a548da67e388d0f85bdfafa8e7e43b 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/SamplePickerPanel.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/SamplePickerPanel.java
@@ -16,17 +16,10 @@
 
 package ch.systemsx.cisd.openbis.dss.client.api.gui;
 
-import java.awt.BorderLayout;
-import java.awt.Insets;
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.FocusListener;
 import java.util.List;
 
-import javax.swing.JButton;
 import javax.swing.JFrame;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
 
 import ch.systemsx.cisd.openbis.dss.client.api.v1.IOpenbisServiceFacade;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment;
@@ -34,81 +27,33 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Experiment;
 /**
  * @author Pawel Glyzewski
  */
-public class SamplePickerPanel extends JPanel
+public class SamplePickerPanel extends AbstractEntityPickerPanel
 {
-
     private static final long serialVersionUID = 1L;
 
-    private static class JTextFieldFireActionPerformedExposed extends JTextField
-    {
-        private static final long serialVersionUID = -7656053161479466883L;
-
-        @Override
-        public void fireActionPerformed()
-        {
-            super.fireActionPerformed();
-        }
-    }
-
-    private final JTextFieldFireActionPerformedExposed textField =
-            new JTextFieldFireActionPerformedExposed();
-
-    private final JButton button = new JButton("...");
-
     private final SamplePickerDialog dialog;
 
     public SamplePickerPanel(final JFrame mainWindow, List<Experiment> experiments,
             IOpenbisServiceFacade openbisService)
     {
-        super(new BorderLayout());
+        super(mainWindow, experiments, openbisService);
 
         dialog = new SamplePickerDialog(mainWindow, experiments, openbisService);
-        button.setMargin(new Insets(button.getMargin().top, 2, button.getMargin().bottom, 2));
-
-        button.addActionListener(new ActionListener()
-            {
-                public void actionPerformed(ActionEvent e)
-                {
-                    String sampleId = dialog.pickSample();
-                    if (sampleId != null)
-                    {
-                        textField.setText(sampleId);
-                        textField.fireActionPerformed();
-                    }
-                }
-            });
-
-        add(textField, BorderLayout.CENTER);
-        add(button, BorderLayout.EAST);
     }
 
-    public String getText()
+    public void actionPerformed(ActionEvent e)
     {
-        return textField.getText();
-    }
-
-    public void setText(String text)
-    {
-        textField.setText(text);
-    }
-
-    public void addActionListener(ActionListener actionListener)
-    {
-        textField.addActionListener(actionListener);
-    }
-
-    @Override
-    public void addFocusListener(FocusListener focusListener)
-    {
-        textField.addFocusListener(focusListener);
-        button.addFocusListener(focusListener);
+        String sampleId = dialog.pickSample();
+        if (sampleId != null)
+        {
+            textField.setText(sampleId);
+            textField.fireActionPerformed();
+        }
     }
 
     @Override
-    public void setEnabled(boolean enabled)
+    protected String getButtonToolTipText()
     {
-        textField.setEditable(enabled);
-        textField.setEnabled(enabled);
-        button.setEnabled(enabled);
+        return "Pick a Sample";
     }
 }