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 b3050c9a32badb7dfc3fec750df1014ab8149edf..ea789d7e18e00c51dd6485782d824fcddc609620 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
@@ -24,6 +24,7 @@ import java.awt.BorderLayout;
 import java.awt.CardLayout;
 import java.awt.Component;
 import java.awt.Dimension;
+import java.awt.Frame;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.Insets;
@@ -31,15 +32,24 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
-import java.util.Arrays;
+import java.io.File;
+import java.util.Enumeration;
 import java.util.List;
 
+import javax.swing.AbstractButton;
+import javax.swing.ButtonGroup;
 import javax.swing.JButton;
 import javax.swing.JComboBox;
+import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
+import javax.swing.JRadioButton;
 import javax.swing.JTextField;
 
+import ch.systemsx.cisd.openbis.dss.client.api.gui.DataSetUploadClientModel.NewDataSetInfo;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwnerType;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTOBuilder;
+
 /**
  * @author Chandrasekhar Ramakrishnan
  */
@@ -47,13 +57,13 @@ public class DataSetMetadataPanel extends JPanel
 {
     private static final long serialVersionUID = 1L;
 
-    private final JTextField sampleIdText;
+    private final JFrame mainWindow;
 
-    private final JButton sampleClearButton;
+    private final DataSetUploadClientModel clientModel;
 
-    private final JTextField experimentIdText;
+    private final JTextField ownerIdText;
 
-    private final JButton experimentClearButton;
+    private final ButtonGroup ownerButtonGroup;
 
     private final JComboBox dataSetTypeComboBox;
 
@@ -61,16 +71,33 @@ public class DataSetMetadataPanel extends JPanel
 
     private final JButton dataSetFileButton;
 
-    public DataSetMetadataPanel()
+    private final JRadioButton experimentButton;
+
+    private final JRadioButton sampleButton;
+
+    // Is set during initialization, but cannot be set in the constructor due to circular
+    // references.
+    private DataSetUploadTableModel tableModel;
+
+    private NewDataSetInfo newDataSetInfo;
+
+    public DataSetMetadataPanel(DataSetUploadClientModel clientModel, JFrame mainWindow)
     {
         super();
         setLayout(new GridBagLayout());
 
+        // Initialize internal state
+        this.clientModel = clientModel;
+        this.mainWindow = mainWindow;
+
         // Initialize the fields in the gui
-        sampleIdText = new JTextField();
-        sampleClearButton = new JButton("Clear");
-        experimentIdText = new JTextField();
-        experimentClearButton = new JButton("Clear");
+        ownerIdText = new JTextField();
+        ownerButtonGroup = new ButtonGroup();
+        experimentButton = new JRadioButton("Experiment");
+        sampleButton = new JRadioButton("Sample");
+        ownerButtonGroup.add(experimentButton);
+        ownerButtonGroup.add(sampleButton);
+
         dataSetTypeComboBox = new JComboBox();
         dataSetTypePanel = new JPanel();
         dataSetFileButton = new JButton("");
@@ -78,37 +105,79 @@ public class DataSetMetadataPanel extends JPanel
         createGui();
     }
 
+    public void setNewDataSetInfo(NewDataSetInfo newDataSetInfo)
+    {
+        this.newDataSetInfo = newDataSetInfo;
+        syncGui();
+    }
+
+    public void setTableModel(DataSetUploadTableModel tableModel)
+    {
+        this.tableModel = tableModel;
+    }
+
+    private void syncGui()
+    {
+        if (null == newDataSetInfo)
+        {
+            ownerIdText.setText("");
+            updateFileLabel();
+            return;
+        }
+
+        NewDataSetDTOBuilder builder = newDataSetInfo.getNewDataSetBuilder();
+        ownerIdText.setText(builder.getDataSetOwnerIdentifier());
+        switch (builder.getDataSetOwnerType())
+        {
+            case EXPERIMENT:
+                ownerButtonGroup.setSelected(experimentButton.getModel(), true);
+                break;
+            case SAMPLE:
+                ownerButtonGroup.setSelected(sampleButton.getModel(), true);
+                break;
+        }
+
+        dataSetTypeComboBox.setSelectedIndex(clientModel.getIndexOfDataSetType(builder
+                .getDataSetMetadata().tryDataSetType()));
+
+        updateFileLabel();
+    }
+
     private void createGui()
     {
-        // The sample row
-        JLabel label = new JLabel("Sample:", JLabel.TRAILING);
+        // The owner row
+        JLabel label = new JLabel("Owner:", JLabel.TRAILING);
         label.setPreferredSize(new Dimension(LABEL_WIDTH, BUTTON_HEIGHT));
 
-        sampleIdText.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT));
-        sampleClearButton.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT));
-        sampleClearButton.setToolTipText("Attach the data set to a sample.");
-        sampleClearButton.addActionListener(new ActionListener()
+        ownerIdText.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT));
+        ownerIdText.addActionListener(new ActionListener()
             {
+
                 public void actionPerformed(ActionEvent e)
                 {
+                    setOwnerId(ownerIdText.getText());
                 }
+
             });
-        addRow(0, label, sampleIdText, sampleClearButton);
 
-        // The experiment row
-        label = new JLabel("Experiment:", JLabel.TRAILING);
-        label.setPreferredSize(new Dimension(LABEL_WIDTH, BUTTON_HEIGHT));
+        experimentButton.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    setOwnerType(DataSetOwnerType.EXPERIMENT);
 
-        experimentIdText.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT));
-        experimentClearButton.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT));
-        experimentClearButton.setToolTipText("Attach the data set to an experiment.");
-        experimentClearButton.addActionListener(new ActionListener()
+                }
+            });
+        experimentButton.setSelected(true);
+        sampleButton.addActionListener(new ActionListener()
             {
                 public void actionPerformed(ActionEvent e)
                 {
+                    setOwnerType(DataSetOwnerType.SAMPLE);
                 }
             });
-        addRow(1, label, experimentIdText, experimentClearButton);
+
+        addRow(0, label, ownerIdText, ownerButtonGroup);
 
         // The data set type row
         label = new JLabel("Data Set Type:", JLabel.TRAILING);
@@ -143,11 +212,38 @@ public class DataSetMetadataPanel extends JPanel
             {
                 public void actionPerformed(ActionEvent e)
                 {
+                    if (null == newDataSetInfo)
+                    {
+                        return;
+                    }
+                    final File newDirOrNull =
+                            ch.systemsx.cisd.common.gui.FileChooserUtils.tryChooseFileOrDirectory(
+                                    getMainWindow(), newDataSetInfo.getNewDataSetBuilder()
+                                            .getFile());
+                    if (newDirOrNull != null)
+                    {
+                        newDataSetInfo.getNewDataSetBuilder().setFile(newDirOrNull);
+                        updateFileLabel();
+                        notifyTableModelOfChanges();
+                    }
                 }
+
             });
         addRow(4, label, dataSetFileButton);
     }
 
+    protected void updateFileLabel()
+    {
+        if (null == newDataSetInfo)
+        {
+            dataSetFileButton.setText("");
+            return;
+        }
+        File file = newDataSetInfo.getNewDataSetBuilder().getFile();
+        String filePath = (null != file) ? file.getAbsolutePath() : "";
+        dataSetFileButton.setText(filePath);
+    }
+
     private void createDataSetTypePanel()
     {
         dataSetTypePanel.setLayout(new CardLayout());
@@ -159,7 +255,7 @@ public class DataSetMetadataPanel extends JPanel
         }
     }
 
-    private void addRow(int rowy, Component label, Component field, Component button)
+    private void addRow(int rowy, Component label, Component field, ButtonGroup buttonGroup)
     {
         GridBagConstraints c = new GridBagConstraints();
         c.fill = GridBagConstraints.HORIZONTAL;
@@ -173,10 +269,17 @@ public class DataSetMetadataPanel extends JPanel
         c.weightx = 0.5;
         c.insets = new Insets((rowy > 0) ? 5 : 0, 0, 0, 5);
         add(field, c);
-        c.gridx = 2;
-        c.weightx = 0;
-        c.insets = new Insets((rowy > 0) ? 5 : 0, 0, 0, 0);
-        add(button, c);
+
+        AbstractButton button;
+        Enumeration<AbstractButton> buttons = buttonGroup.getElements();
+        while (buttons.hasMoreElements())
+        {
+            button = buttons.nextElement();
+            ++c.gridx;
+            c.weightx = 0;
+            c.insets = new Insets((rowy > 0) ? 5 : 0, 0, 0, buttons.hasMoreElements() ? 5 : 0);
+            add(button, c);
+        }
     }
 
     private void addRow(int rowy, Component label, Component field)
@@ -208,8 +311,41 @@ public class DataSetMetadataPanel extends JPanel
 
     private List<String> getDataSetTypes()
     {
-        String[] dataSetTypes =
-            { "Data Set Type 1", "Data Set Type 2", "Data Set Type 3" };
-        return Arrays.asList(dataSetTypes);
+        return clientModel.getDataSetTypes();
+    }
+
+    private Frame getMainWindow()
+    {
+        return mainWindow;
+    }
+
+    private void notifyTableModelOfChanges()
+    {
+        tableModel.selectedRowChanged();
+    }
+
+    private void setOwnerType(DataSetOwnerType type)
+    {
+        if (null == newDataSetInfo)
+        {
+            return;
+        }
+
+        NewDataSetDTOBuilder builder = newDataSetInfo.getNewDataSetBuilder();
+        builder.setDataSetOwnerType(type);
+
+        notifyTableModelOfChanges();
+    }
+
+    protected void setOwnerId(String text)
+    {
+        if (null == newDataSetInfo)
+        {
+            return;
+        }
+
+        NewDataSetDTOBuilder builder = newDataSetInfo.getNewDataSetBuilder();
+        builder.setDataSetOwnerIdentifier(text);
+        notifyTableModelOfChanges();
     }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadClient.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadClient.java
index 123be5296c1a03813f99041bef9f10311e339c41..20a7c3ab6891e90604aae17f24950cfa971a201b 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadClient.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadClient.java
@@ -103,13 +103,18 @@ public class DataSetUploadClient extends AbstractSwingGUI
 
     private final DataSetUploadTableModel tableModel;
 
+    private final DataSetMetadataPanel metadataPanel;
+
     DataSetUploadClient(final DssCommunicationState commState, final ITimeProvider timeProvider)
     {
         // save and create local state
         super(commState);
 
         clientModel = new DataSetUploadClientModel(getDssComponent(), timeProvider);
-        tableModel = new DataSetUploadTableModel(this, clientModel, getWindowFrame());
+        metadataPanel = new DataSetMetadataPanel(clientModel, getWindowFrame());
+        tableModel =
+                new DataSetUploadTableModel(this, clientModel, metadataPanel, getWindowFrame());
+        metadataPanel.setTableModel(tableModel);
 
         createGui();
         addProgressListener();
@@ -144,7 +149,7 @@ public class DataSetUploadClient extends AbstractSwingGUI
         c.gridy = 2;
         c.weightx = 0.5;
         c.weighty = 0.5;
-        panel.add(createMetadataPanel(), c);
+        panel.add(metadataPanel, c);
 
         window.add(panel, BorderLayout.CENTER);
 
@@ -170,6 +175,28 @@ public class DataSetUploadClient extends AbstractSwingGUI
         JPanel panel = new JPanel();
         panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
 
+        JButton addButton = new JButton("+");
+        addButton.setPreferredSize(new Dimension(50, BUTTON_HEIGHT));
+        addButton.setToolTipText("Add a new data set");
+        addButton.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    tableModel.addNewDataSet();
+                }
+            });
+
+        JButton removeButton = new JButton("-");
+        removeButton.setPreferredSize(new Dimension(50, BUTTON_HEIGHT));
+        removeButton.setToolTipText("Remove the selected data set");
+        removeButton.addActionListener(new ActionListener()
+            {
+                public void actionPerformed(ActionEvent e)
+                {
+                    tableModel.removeSelectedDataSet();
+                }
+            });
+
         JButton uploadAllButton = new JButton("Upload All");
         uploadAllButton.setPreferredSize(new Dimension(BUTTON_WIDTH, BUTTON_HEIGHT));
         uploadAllButton.setToolTipText("Attach the data set to a sample.");
@@ -180,6 +207,8 @@ public class DataSetUploadClient extends AbstractSwingGUI
                 }
             });
 
+        panel.add(addButton);
+        panel.add(removeButton);
         panel.add(Box.createHorizontalGlue());
         panel.add(uploadAllButton);
 
@@ -238,7 +267,6 @@ public class DataSetUploadClient extends AbstractSwingGUI
         column =
                 fileTable.getColumnModel().getColumn(DataSetUploadTableModel.DATA_SET_OWNER_COLUMN);
         column.setPreferredWidth(320);
-        column.setCellRenderer(new FileDetailsTableCellRenderer());
 
         column =
                 fileTable.getColumnModel().getColumn(
@@ -250,17 +278,12 @@ public class DataSetUploadClient extends AbstractSwingGUI
 
         column = fileTable.getColumnModel().getColumn(DataSetUploadTableModel.UPLOAD_STATUS_COLUMN);
         column.setPreferredWidth(150);
-        column.setCellRenderer(new DownloadStatusTableCellRenderer(tableModel));
-        column.setCellEditor(new DownloadStatusTableCellEditor(tableModel));
+        column.setCellRenderer(new UploadStatusTableCellRenderer(tableModel));
+        column.setCellEditor(new UploadStatusTableCellEditor(tableModel));
         JScrollPane scrollPane = new JScrollPane(fileTable);
         return scrollPane;
     }
 
-    private JComponent createMetadataPanel()
-    {
-        return new DataSetMetadataPanel();
-    }
-
     private void addProgressListener()
     {
     }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadClientModel.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadClientModel.java
index f6d9117448bf0ff75460adef80fa011f5a9e8fe5..76610f168ffc02d60ef1fd3f038fc35e330d3741 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadClientModel.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadClientModel.java
@@ -16,14 +16,15 @@
 
 package ch.systemsx.cisd.openbis.dss.client.api.gui;
 
-import java.io.File;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
 import ch.systemsx.cisd.common.io.TransmissionSpeedCalculator;
 import ch.systemsx.cisd.common.utilities.ITimeProvider;
 import ch.systemsx.cisd.openbis.dss.client.api.v1.IDssComponent;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssDTO;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTOBuilder;
 
 /**
@@ -71,8 +72,6 @@ public class DataSetUploadClientModel
 
         private final TransmissionSpeedCalculator transmissionSpeedCalculator;
 
-        private File file;
-
         private Status status;
 
         // Computed when the status is set to QUEUED_FOR_UPLOAD
@@ -92,11 +91,6 @@ public class DataSetUploadClientModel
             setStatus(Status.TO_UPLOAD);
         }
 
-        public NewDataSetDTO getNewDataSet()
-        {
-            return newDataSetBuilder.asNewDataSetDTO();
-        }
-
         public NewDataSetDTOBuilder getNewDataSetBuilder()
         {
             return newDataSetBuilder;
@@ -107,16 +101,6 @@ public class DataSetUploadClientModel
             return totalFileSize;
         }
 
-        public File getFile()
-        {
-            return file;
-        }
-
-        public void setFile(File aFile)
-        {
-            this.file = aFile;
-        }
-
         public int getPercentageDownloaded()
         {
             return percentageUploaded;
@@ -179,9 +163,9 @@ public class DataSetUploadClientModel
     /**
      * A list of data set info object managed by this model.
      */
-    public ArrayList<NewDataSetInfo> getNewDataSetInfos()
+    public List<NewDataSetInfo> getNewDataSetInfos()
     {
-        return newDataSetInfos;
+        return Collections.unmodifiableList(newDataSetInfos);
     }
 
     /**
@@ -195,9 +179,41 @@ public class DataSetUploadClientModel
         return newDataSetInfo;
     }
 
+    /**
+     * Remove a data set info.
+     */
+    public void removeNewDataSetInfo(NewDataSetInfo dataSetInfoToRemove)
+    {
+        newDataSetInfos.remove(dataSetInfoToRemove);
+    }
+
     public IDssComponent getDssComponent()
     {
         return dssComponent;
     }
 
+    /**
+     * Get the data set types that are shown here.
+     */
+    public List<String> getDataSetTypes()
+    {
+        String[] dataSetTypes =
+            { "Data Set Type 1", "Data Set Type 2", "Data Set Type 3" };
+        return Arrays.asList(dataSetTypes);
+    }
+
+    public int getIndexOfDataSetType(String dataSetType)
+    {
+        if (null == dataSetType)
+        {
+            return 0;
+        }
+        int index = getDataSetTypes().indexOf(dataSetType);
+        if (index < 0)
+        {
+            return 0;
+        }
+        return index;
+    }
+
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadOperation.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadOperation.java
index ae03a85ee47fbf49ed6a740aa6859042333f1707..86c325d69b4dec3a51530ca3ee304709fb5596a6 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadOperation.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadOperation.java
@@ -52,12 +52,15 @@ final class DataSetUploadOperation implements Runnable
             {
                 newDataSetInfo.setStatus(Status.UPLOADING);
                 tableModel.fireChanged(newDataSetInfo, Status.UPLOADING);
-                clientModel.getDssComponent().putDataSet(newDataSetInfo.getNewDataSet(),
-                        newDataSetInfo.getFile());
+                clientModel.getDssComponent().putDataSet(
+                        newDataSetInfo.getNewDataSetBuilder().asNewDataSetDTO(),
+                        newDataSetInfo.getNewDataSetBuilder().getFile());
             }
+            newDataSetInfo.setStatus(Status.COMPLETED_UPLOAD);
             tableModel.fireChanged(newDataSetInfo, Status.COMPLETED_UPLOAD);
         } catch (Throwable th)
         {
+            newDataSetInfo.setStatus(Status.FAILED);
             tableModel.fireChanged(newDataSetInfo, Status.FAILED);
             final Throwable actualTh =
                     (th instanceof Error) ? th : CheckedExceptionTunnel
@@ -65,7 +68,8 @@ final class DataSetUploadOperation implements Runnable
             if (actualTh instanceof FileExistsException == false)
             {
                 DataSetUploadClient.notifyUserOfThrowable(tableModel.getMainWindow(),
-                        newDataSetInfo.getFile().getAbsolutePath(), "Uploading", th, null);
+                        newDataSetInfo.getNewDataSetBuilder().getFile().getAbsolutePath(),
+                        "Uploading", th, null);
             }
         }
     }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadTableModel.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadTableModel.java
index 260634de77b4cacb334125586beb6fdd8a7d53ff..535f44e20ccc771de1a8fbf89ed29f2c01c57bc4 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadTableModel.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DataSetUploadTableModel.java
@@ -36,11 +36,11 @@ import javax.swing.table.TableColumnModel;
 import ch.systemsx.cisd.base.namedthread.NamingThreadPoolExecutor;
 import ch.systemsx.cisd.openbis.dss.client.api.gui.DataSetUploadClientModel.NewDataSetInfo;
 import ch.systemsx.cisd.openbis.dss.client.api.gui.DataSetUploadClientModel.NewDataSetInfo.Status;
-import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwner;
 
 /**
  * The DataSetUploadClientModel manages the list of data sets to register, initiates uploads (which
- * run in a separate thread) and notifies the GUI of updates.
+ * run in a separate thread) and notifies the GUI of updates. It also coordinates the Metadata panel
+ * to ensure the two are in sync.
  * 
  * @author Chandrasekhar Ramakrishnan
  */
@@ -63,16 +63,21 @@ public class DataSetUploadTableModel extends AbstractTableModel
 
     private final JFrame mainWindow;
 
+    private final DataSetUploadClientModel clientModel;
+
+    private final DataSetMetadataPanel metadataPanel;
+
     private final ArrayList<DataSetUploadClientModel.NewDataSetInfo> newDataSetInfos =
             new ArrayList<DataSetUploadClientModel.NewDataSetInfo>();
 
-    private final DataSetUploadClientModel clientModel;
-
     private JTable table;
 
-    protected int sortColumnIndex = 0;
+    private int sortColumnIndex = 0;
+
+    private boolean sortAscending = true;
 
-    protected boolean sortAscending = true;
+    // Initialize to no row selected
+    private int selectedRow = -1;
 
     /**
      * Internal class for triggering the sorting of columns.
@@ -109,12 +114,10 @@ public class DataSetUploadTableModel extends AbstractTableModel
                 TableColumn column = colModel.getColumn(i);
                 column.setHeaderValue(getColumnName(column.getModelIndex()));
             }
-            table.getTableHeader().repaint();
 
-            Collections.sort(newDataSetInfos, new NewDataSetInfoComparator());
+            table.getTableHeader().repaint();
 
-            table.tableChanged(new TableModelEvent(DataSetUploadTableModel.this));
-            table.repaint();
+            syncNewDataSetInfoListView();
         }
     }
 
@@ -131,15 +134,13 @@ public class DataSetUploadTableModel extends AbstractTableModel
             switch (sortColumnIndex)
             {
                 case DATA_SET_OWNER_COLUMN:
-                    DataSetOwner owner1 = info1.getNewDataSetBuilder().getDataSetOwner();
-                    DataSetOwner owner2 = info2.getNewDataSetBuilder().getDataSetOwner();
-                    String identifier1 = (null != owner1) ? owner1.getIdentifier() : "";
-                    String identifier2 = (null != owner2) ? owner2.getIdentifier() : "";
+                    String identifier1 = info1.getNewDataSetBuilder().getDataSetOwnerIdentifier();
+                    String identifier2 = info2.getNewDataSetBuilder().getDataSetOwnerIdentifier();
                     result = identifier1.compareTo(identifier2);
                     break;
                 case DATA_SET_PATH_COLUMN:
-                    File file1 = info1.getFile();
-                    File file2 = info2.getFile();
+                    File file1 = info1.getNewDataSetBuilder().getFile();
+                    File file2 = info2.getNewDataSetBuilder().getFile();
                     String path1 = (null != file1) ? file1.getAbsolutePath() : "";
                     String path2 = (null != file2) ? file2.getAbsolutePath() : "";
                     result = path1.compareTo(path2);
@@ -153,12 +154,12 @@ public class DataSetUploadTableModel extends AbstractTableModel
     }
 
     DataSetUploadTableModel(DataSetUploadClient downloadClient,
-            DataSetUploadClientModel clientModel, JFrame mainWindow)
+            DataSetUploadClientModel clientModel, DataSetMetadataPanel metadataPanel,
+            JFrame mainWindow)
     {
         this.mainWindow = mainWindow;
         this.clientModel = clientModel;
-
-        addProgessListener();
+        this.metadataPanel = metadataPanel;
     }
 
     public void setTable(JTable table)
@@ -167,69 +168,6 @@ public class DataSetUploadTableModel extends AbstractTableModel
         table.getTableHeader().addMouseListener(new ColumnSortingListener());
     }
 
-    private void addProgessListener()
-    {
-        // TODO
-        // downloader.addProgressListener(new IProgressListener()
-        // {
-        // public void start(File file, String operationname, long fileSize, Long fileIdOrNull)
-        // {
-        // currentlyDownloadingFile = tryToFindDownloadInfoForFile(fileIdOrNull);
-        // if (currentlyDownloadingFile != null)
-        // {
-        // currentlyDownloadingFile.updateProgress(0, 0);
-        // fireChanged(null);
-        // }
-        // }
-        //
-        // public void reportProgress(int percentage, long numberOfBytes)
-        // {
-        // if (currentlyDownloadingFile != null)
-        // {
-        // currentlyDownloadingFile.updateProgress(percentage, numberOfBytes);
-        // fireChanged(null);
-        // }
-        // }
-        //
-        // public void finished(boolean successful)
-        // {
-        // if (currentlyDownloadingFile != null)
-        // {
-        // if (successful)
-        // {
-        // currentlyDownloadingFile.updateProgress(100,
-        // currentlyDownloadingFile.fileInfoDTO.getSize());
-        // if (passphrase.length() > 0)
-        // {
-        // currentlyDownloadingFile
-        // .setStatus(FileDownloadInfo.Status.DECRYPTING);
-        // fireChanged(FileDownloadInfo.Status.DECRYPTING);
-        // } else
-        // {
-        // currentlyDownloadingFile
-        // .setStatus(FileDownloadInfo.Status.COMPLETED_DOWNLOAD);
-        // fireChanged(FileDownloadInfo.Status.COMPLETED_DOWNLOAD);
-        // }
-        // } else
-        // {
-        // currentlyDownloadingFile.setStatus(FileDownloadInfo.Status.FAILED);
-        // fireChanged(FileDownloadInfo.Status.FAILED);
-        // }
-        // }
-        // }
-        //
-        // public void exceptionOccured(Throwable throwable)
-        // {
-        // }
-        //
-        // public void warningOccured(String warningMessage)
-        // {
-        // currentlyDownloadingFile.setStatus(FileDownloadInfo.Status.STALLED);
-        // }
-        //
-        // });
-    }
-
     /**
      * Notification that the status of the newDataSetInfo has changed.
      * 
@@ -244,7 +182,14 @@ public class DataSetUploadTableModel extends AbstractTableModel
 
     void setSelectedIndices(ArrayList<Integer> selectedIndices)
     {
-
+        if (selectedIndices.size() < 1)
+        {
+            selectNewDataSetInfo(null);
+            return;
+        }
+        selectedRow = selectedIndices.get(0);
+        NewDataSetInfo selectedDataSet = newDataSetInfos.get(selectedRow);
+        selectNewDataSetInfo(selectedDataSet);
     }
 
     public int getColumnCount()
@@ -293,7 +238,7 @@ public class DataSetUploadTableModel extends AbstractTableModel
             case DATA_SET_METADATA_COLUMN:
                 return newDataSetInfo.getNewDataSetBuilder().getDataSetMetadata();
             case DATA_SET_PATH_COLUMN:
-                return newDataSetInfo.getFile();
+                return newDataSetInfo.getNewDataSetBuilder().getFile();
             case UPLOAD_STATUS_COLUMN:
                 return newDataSetInfo;
         }
@@ -327,8 +272,9 @@ public class DataSetUploadTableModel extends AbstractTableModel
 
         // Only start uploading if the file hasn't been upload yet
         NewDataSetInfo.Status status = newDataSetInfo.getStatus();
-        if ((status == NewDataSetInfo.Status.TO_UPLOAD)
-                || (status != NewDataSetInfo.Status.COMPLETED_UPLOAD))
+        if ((status != NewDataSetInfo.Status.TO_UPLOAD)
+                && (status != NewDataSetInfo.Status.COMPLETED_UPLOAD)
+                && (status != NewDataSetInfo.Status.FAILED))
         {
             return;
         }
@@ -360,6 +306,55 @@ public class DataSetUploadTableModel extends AbstractTableModel
                 || (status == NewDataSetInfo.Status.COMPLETED_UPLOAD);
     }
 
+    public JFrame getMainWindow()
+    {
+        return mainWindow;
+    }
+
+    public void selectedRowChanged()
+    {
+        if (selectedRow < 0)
+        {
+            return;
+        }
+        fireTableRowsUpdated(selectedRow, selectedRow);
+    }
+
+    public void addNewDataSet()
+    {
+        NewDataSetInfo newlyCreated = clientModel.addNewDataSetInfo();
+        syncNewDataSetInfos();
+        selectNewDataSetInfo(newlyCreated);
+    }
+
+    public void removeSelectedDataSet()
+    {
+        assert false : "Not yet implemented";
+    }
+
+    /**
+     * Synchronize the internal list of data set infos with the model's list.
+     */
+    private void syncNewDataSetInfos()
+    {
+        newDataSetInfos.clear();
+        newDataSetInfos.addAll(clientModel.getNewDataSetInfos());
+        syncNewDataSetInfoListView();
+    }
+
+    private void syncNewDataSetInfoListView()
+    {
+        Collections.sort(newDataSetInfos, new NewDataSetInfoComparator());
+
+        table.tableChanged(new TableModelEvent(DataSetUploadTableModel.this));
+        table.repaint();
+    }
+
+    private void selectNewDataSetInfo(NewDataSetInfo newDataSetInfo)
+    {
+        metadataPanel.setNewDataSetInfo(newDataSetInfo);
+    }
+
     /**
      * Start a data set upload in a separate thread. Callers need to ensure that queuing makes
      * sense.
@@ -371,8 +366,8 @@ public class DataSetUploadTableModel extends AbstractTableModel
         executor.submit(op);
     }
 
-    public JFrame getMainWindow()
+    public NewDataSetInfo getSelectedNewDataSet()
     {
-        return mainWindow;
+        return newDataSetInfos.get(selectedRow);
     }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/FileDetailsTableCellRenderer.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/FileDetailsTableCellRenderer.java
index 860ca29e9f156158fbcbe8958532421794531f3a..e4f5318c6304f688ac0db1651522d2500917b904 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/FileDetailsTableCellRenderer.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/FileDetailsTableCellRenderer.java
@@ -20,6 +20,7 @@ import java.awt.Color;
 import java.awt.Component;
 import java.awt.Font;
 import java.awt.GridLayout;
+import java.io.File;
 import java.util.Formatter;
 
 import javax.swing.JLabel;
@@ -27,7 +28,7 @@ import javax.swing.JPanel;
 import javax.swing.JTable;
 import javax.swing.table.TableCellRenderer;
 
-import ch.systemsx.cisd.cifex.shared.basic.dto.FileInfoDTO;
+import ch.systemsx.cisd.openbis.dss.client.api.gui.DataSetUploadClientModel.NewDataSetInfo;
 
 /**
  * Shows file name and file size in a table cell
@@ -60,12 +61,19 @@ public class FileDetailsTableCellRenderer implements TableCellRenderer
     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
             boolean hasFocus, int row, int column)
     {
-        FileInfoDTO fileInfo = (FileInfoDTO) value;
+        NewDataSetInfo newDataSetInfo = (NewDataSetInfo) value;
         Color backgroundColor =
                 (isSelected) ? table.getSelectionBackground() : table.getBackground();
         panel.setBackground(backgroundColor);
-        fileName.setText(fileInfo.getName());
-        fileSize.setText(numberOfBytesToDisplayString(fileInfo.getSize()));
+
+        if (null == newDataSetInfo)
+        {
+            return panel;
+        }
+        File file = newDataSetInfo.getNewDataSetBuilder().getFile();
+        String fileString = (null != file) ? file.getName() : "";
+        fileName.setText(fileString);
+        fileSize.setText(numberOfBytesToDisplayString(newDataSetInfo.getTotalFileSize()));
         return panel;
     }
 
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DownloadStatusTableCellEditor.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/UploadStatusTableCellEditor.java
similarity index 88%
rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DownloadStatusTableCellEditor.java
rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/UploadStatusTableCellEditor.java
index e406d892ca7cbff2c99160a460ce58f4dddbe166..62ee0b014eea80c128f421399579c751b324f9eb 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DownloadStatusTableCellEditor.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/UploadStatusTableCellEditor.java
@@ -30,16 +30,16 @@ import javax.swing.table.TableCellEditor;
  * 
  * @author Chandrasekhar Ramakrishnan
  */
-public class DownloadStatusTableCellEditor extends AbstractCellEditor implements TableCellEditor
+public class UploadStatusTableCellEditor extends AbstractCellEditor implements TableCellEditor
 {
 
     private static final long serialVersionUID = 1L;
 
-    final JButton button = new JButton("Download");
+    final JButton button = new JButton("Upload");
 
     final DataSetUploadTableModel tableModel;
 
-    DownloadStatusTableCellEditor(DataSetUploadTableModel tableModel)
+    UploadStatusTableCellEditor(DataSetUploadTableModel tableModel)
     {
         super();
         this.tableModel = tableModel;
@@ -71,6 +71,6 @@ public class DownloadStatusTableCellEditor extends AbstractCellEditor implements
 
     public Object getCellEditorValue()
     {
-        return null;
+        return tableModel.getSelectedNewDataSet();
     }
 }
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DownloadStatusTableCellRenderer.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/UploadStatusTableCellRenderer.java
similarity index 66%
rename from datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DownloadStatusTableCellRenderer.java
rename to datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/UploadStatusTableCellRenderer.java
index 36c9b222b0c2b53f4e040810d29ba9180fd21c17..654d86bd6c7cfac1463e16134c4d8354821e7e98 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/DownloadStatusTableCellRenderer.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/gui/UploadStatusTableCellRenderer.java
@@ -33,11 +33,11 @@ import javax.swing.table.TableCellRenderer;
  * 
  * @author Chandrasekhar Ramakrishnan
  */
-public class DownloadStatusTableCellRenderer implements TableCellRenderer
+public class UploadStatusTableCellRenderer implements TableCellRenderer
 {
-    private final JButton downloadButton = new JButton("Download");
+    private final JButton uploadButton = new JButton("Upload");
 
-    private final JPanel downloadPanel = new JPanel();
+    private final JPanel uploadPanel = new JPanel();
 
     private final JProgressBar progressBar = new JProgressBar();
 
@@ -45,13 +45,9 @@ public class DownloadStatusTableCellRenderer implements TableCellRenderer
 
     private final JPanel progressPanel = new JPanel();
 
-    private final JLabel decryptingLabel = new JLabel("Decrypting\u2026");
+    private final JButton retryButton = new JButton("Retry Upload");
 
-    private final JPanel decryptingPanel = new JPanel();
-
-    private final JButton retryButton = new JButton("Retry Download");
-
-    private final JLabel retryLabel = new JLabel("<html><i>Download Failed</i></html>");
+    private final JLabel retryLabel = new JLabel("<html><i>Upload Failed</i></html>");
 
     private final JPanel retryPanel = new JPanel();
 
@@ -59,21 +55,13 @@ public class DownloadStatusTableCellRenderer implements TableCellRenderer
 
     private final JPanel completedPanel = new JPanel();
 
-    private final JButton decryptButton = new JButton("Decrypt");
-
-    private final JLabel completedDownloadLabel = new JLabel("Finished Download");
-
-    private final JPanel completedDownloadPanel = new JPanel();
-
-    public DownloadStatusTableCellRenderer(DataSetUploadTableModel tableModel)
+    public UploadStatusTableCellRenderer(DataSetUploadTableModel tableModel)
     {
         super();
         createDownloadPanel();
         createProgressPanel();
         createRetryPanel();
-        createDecryptingPanel();
         createCompletedPanel();
-        createCompletedNotDecryptedPanel();
     }
 
     private void createCompletedPanel()
@@ -84,23 +72,6 @@ public class DownloadStatusTableCellRenderer implements TableCellRenderer
         completedPanel.setOpaque(true);
     }
 
-    private void createCompletedNotDecryptedPanel()
-    {
-        completedDownloadPanel.setLayout(new GridLayout(2, 0));
-        completedDownloadLabel.setFont(completedDownloadLabel.getFont().deriveFont(Font.PLAIN));
-        completedDownloadPanel.add(completedDownloadLabel);
-        completedDownloadPanel.add(decryptButton);
-        completedDownloadPanel.setOpaque(true);
-    }
-
-    private void createDecryptingPanel()
-    {
-        decryptingPanel.setLayout(new GridLayout(1, 0));
-        decryptingPanel.setFont(decryptingLabel.getFont().deriveFont(Font.PLAIN));
-        decryptingPanel.add(decryptingLabel);
-        decryptingPanel.setOpaque(true);
-    }
-
     private void createRetryPanel()
     {
         retryPanel.setLayout(new GridLayout(2, 0));
@@ -121,9 +92,9 @@ public class DownloadStatusTableCellRenderer implements TableCellRenderer
 
     private void createDownloadPanel()
     {
-        downloadPanel.setLayout(new GridLayout(1, 0));
-        downloadPanel.add(downloadButton);
-        downloadPanel.setOpaque(true);
+        uploadPanel.setLayout(new GridLayout(1, 0));
+        uploadPanel.add(uploadButton);
+        uploadPanel.setOpaque(true);
     }
 
     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
@@ -136,7 +107,7 @@ public class DownloadStatusTableCellRenderer implements TableCellRenderer
         switch (0)
         {
             case 0:
-                panel = downloadPanel;
+                panel = uploadPanel;
                 break;
             case 1:
                 panel = completedPanel;
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTOBuilder.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTOBuilder.java
index 8fba437f0815817324618e335e32f0c48dcc417f..d2d4c1ee22d91a74943e7871b9ca19b68ffa45cc 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTOBuilder.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/NewDataSetDTOBuilder.java
@@ -16,10 +16,14 @@
 
 package ch.systemsx.cisd.openbis.dss.generic.shared.api.v1;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
+import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwner;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwnerType;
 
 /**
  * A mutable object for building NewDataSetDTO objects.
@@ -30,11 +34,11 @@ public class NewDataSetDTOBuilder
 {
     private final NewDataSetMetadataDTO dataSetMetadata;
 
-    private DataSetOwner dataSetOwner;
+    private String dataSetOwnerIdentifier;
 
-    private String dataSetFolderNameOrNull;
+    private DataSetOwnerType dataSetOwnerType = DataSetOwnerType.EXPERIMENT;
 
-    private final ArrayList<FileInfoDssDTO> fileInfos = new ArrayList<FileInfoDssDTO>();
+    private File file;
 
     public NewDataSetDTOBuilder()
     {
@@ -42,34 +46,38 @@ public class NewDataSetDTOBuilder
     }
 
     /**
-     * The owner may be null during construction but is non-null in a well-formed object.
+     * The owner identifier may be and empty during construction but is non-null in a well-formed
+     * object.
      */
-    public DataSetOwner getDataSetOwner()
+    public String getDataSetOwnerIdentifier()
     {
-        return dataSetOwner;
+        return (null == dataSetOwnerIdentifier) ? "" : dataSetOwnerIdentifier;
     }
 
-    public void setDataSetOwner(DataSetOwner dataSetOwner)
+    public void setDataSetOwnerIdentifier(String dataSetOwnerIdentifier)
     {
-        this.dataSetOwner = dataSetOwner;
+        this.dataSetOwnerIdentifier = dataSetOwnerIdentifier;
     }
 
     /**
-     * The optional folder name that the contents of the data set should be put in on the server. If
-     * null, a folder name may be generated.
+     * The owner type should never be null.
      */
-    public String getDataSetFolderNameOrNull()
+    public DataSetOwnerType getDataSetOwnerType()
+    {
+        return dataSetOwnerType;
+    }
+
+    public void setDataSetOwnerType(DataSetOwnerType dataSetOwnerType)
     {
-        return dataSetFolderNameOrNull;
+        this.dataSetOwnerType = dataSetOwnerType;
     }
 
     /**
-     * The optional folder name that the contents of the data set should be put in on the server. If
-     * null, a folder name may be generated.
+     * The owner may be null during construction but is non-null in a well-formed object.
      */
-    public void setDataSetFolderNameOrNull(String dataSetFolderNameOrNull)
+    public DataSetOwner getDataSetOwner()
     {
-        this.dataSetFolderNameOrNull = dataSetFolderNameOrNull;
+        return new DataSetOwner(getDataSetOwnerType(), getDataSetOwnerIdentifier());
     }
 
     /**
@@ -81,11 +89,45 @@ public class NewDataSetDTOBuilder
     }
 
     /**
-     * A summary of the contents of the data set.
+     * The file that contains the data set. May be null during initialization but should be non-null
+     * in a well-formed data set.
      */
+    public File getFile()
+    {
+        return file;
+    }
+
+    /**
+     * Set the file that contains the data set.
+     */
+    public void setFile(File file)
+    {
+        this.file = file;
+    }
+
     public List<FileInfoDssDTO> getFileInfos()
     {
-        return fileInfos;
+        try
+        {
+            ArrayList<FileInfoDssDTO> fileInfos = new ArrayList<FileInfoDssDTO>();
+            if (false == file.exists())
+            {
+                return fileInfos;
+            }
+
+            String path = file.getCanonicalPath();
+            if (false == file.isDirectory())
+            {
+                path = file.getParentFile().getCanonicalPath();
+            }
+
+            FileInfoDssBuilder builder = new FileInfoDssBuilder(path, path);
+            builder.appendFileInfosForFile(file, fileInfos, true);
+            return fileInfos;
+        } catch (IOException e)
+        {
+            throw new IOExceptionUnchecked(e);
+        }
     }
 
     /**
@@ -93,7 +135,9 @@ public class NewDataSetDTOBuilder
      */
     public NewDataSetDTO asNewDataSetDTO()
     {
-        return new NewDataSetDTO(dataSetMetadata, dataSetOwner, dataSetFolderNameOrNull, fileInfos);
+        String dataSetFolderNameOrNull = (file.isDirectory()) ? file.getName() : null;
+        return new NewDataSetDTO(dataSetMetadata, getDataSetOwner(), dataSetFolderNameOrNull,
+                getFileInfos());
     }
 
 }