From d93f04c0cbb9f14b67d44121175c9d5ab909ef06 Mon Sep 17 00:00:00 2001
From: kaloyane <kaloyane>
Date: Mon, 14 Feb 2011 23:13:47 +0000
Subject: [PATCH] [LMS-2019] Enhanced merged channel selection (initial
 version)

SVN: 19940
---
 .../ScreeningDisplaySettingsManager.java      |  21 +-
 .../detailviewers/ChannelChooser.java         |  44 ++-
 .../detailviewers/ChannelChooserPanel.java    | 296 ++++++++++++++++++
 .../detailviewers/ChannelComboBox.java        | 123 --------
 .../ChannelWidgetWithListener.java            |  40 +--
 .../detailviewers/DefaultChannelState.java    |  55 ++++
 .../detailviewers/IDefaultChannelState.java   |   9 +-
 .../detailviewers/ImageUrlUtils.java          |  31 +-
 .../detailviewers/LogicalImageViewer.java     |  60 ++--
 .../detailviewers/WellContentDialog.java      |  14 +-
 .../detailviewers/WellSearchGrid.java         |  40 +--
 .../dto/LogicalImageChannelsReference.java    |  15 +-
 12 files changed, 478 insertions(+), 270 deletions(-)
 create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooserPanel.java
 delete mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelComboBox.java
 create mode 100644 screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/DefaultChannelState.java

diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ScreeningDisplaySettingsManager.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ScreeningDisplaySettingsManager.java
index 004ec4b3269..d7115f73fdd 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ScreeningDisplaySettingsManager.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/ScreeningDisplaySettingsManager.java
@@ -16,6 +16,10 @@
 
 package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application;
 
+import java.util.Arrays;
+import java.util.List;
+
+import ch.systemsx.cisd.common.shared.basic.utils.StringUtils;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.DisplaySettingsManager;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningDisplaySettings;
@@ -25,6 +29,9 @@ import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningDispl
  */
 public class ScreeningDisplaySettingsManager
 {
+
+    private static final String DELIMITER = ",";
+
     private final ScreeningDisplaySettings screeningSettings;
 
     @SuppressWarnings("deprecation")
@@ -46,15 +53,21 @@ public class ScreeningDisplaySettingsManager
     // delegate
 
     @SuppressWarnings("deprecation")
-    public String tryGetDefaultChannel(String displayTypeID)
+    public List<String> tryGetDefaultChannels(String displayTypeID)
     {
-        return screeningSettings.getDefaultChannels().get(displayTypeID);
+        String channelListString = screeningSettings.getDefaultChannels().get(displayTypeID);
+        if (channelListString != null)
+        {
+            return Arrays.asList(channelListString.split(","));
+        }
+        return null;
     }
 
     @SuppressWarnings("deprecation")
-    public void setDefaultChannel(String displayTypeID, String channel)
+    public void setDefaultChannels(String displayTypeID, List<String> channels)
     {
-        screeningSettings.getDefaultChannels().put(displayTypeID, channel);
+        String channelListString = StringUtils.join(channels.toArray(new String[0]), DELIMITER);
+        screeningSettings.getDefaultChannels().put(displayTypeID, channelListString);
     }
 
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooser.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooser.java
index 5baf8ff6ec4..071cb7fc7a4 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooser.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooser.java
@@ -21,6 +21,9 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import com.extjs.gxt.ui.client.widget.LayoutContainer;
+import com.google.gwt.user.client.ui.Widget;
+
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.CheckBoxGroupWithModel;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.CheckBoxGroupWithModel.CheckBoxGroupListner;
 import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.widget.LabeledItem;
@@ -30,13 +33,6 @@ import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.d
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.utils.GuiUtils;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetImagesReference;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetParameters;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants;
-
-import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
-import com.extjs.gxt.ui.client.event.SelectionChangedListener;
-import com.extjs.gxt.ui.client.widget.LayoutContainer;
-import com.extjs.gxt.ui.client.widget.form.SimpleComboValue;
-import com.google.gwt.user.client.ui.Widget;
 
 /**
  * Handles displaying images in different channels and allows to choose the overlays.
@@ -71,7 +67,7 @@ class ChannelChooser
 
     private Set<ImageDatasetChannel> selectedOverlayChannels;
 
-    private String basicImageChannelCode;
+    private List<String> basicChannelCodes;
 
     public ChannelChooser(LogicalImageReference basicImage, IChanneledViewerFactory viewerFactory,
             IDefaultChannelState defaultChannelState)
@@ -80,8 +76,8 @@ class ChannelChooser
         this.viewerFactory = viewerFactory;
         this.imageContainer = new LayoutContainer();
 
-        this.basicImageChannelCode =
-                getInitialChannelCode(defaultChannelState, basicImage.getChannelsCodes());
+        this.basicChannelCodes =
+                getInitialChannelCodes(defaultChannelState, basicImage.getChannelsCodes());
         this.defaultChannelState = defaultChannelState;
         this.selectedOverlayChannels = new HashSet<ImageDatasetChannel>();
     }
@@ -97,7 +93,7 @@ class ChannelChooser
     public void refresh()
     {
         LogicalImageChannelsReference state =
-                new LogicalImageChannelsReference(basicImage, basicImageChannelCode,
+                new LogicalImageChannelsReference(basicImage, basicChannelCodes,
                         selectedOverlayChannels);
         Widget view = viewerFactory.create(state);
         imageContainer.removeAll();
@@ -182,33 +178,31 @@ class ChannelChooser
 
     private Widget createBasicChannelChooser(List<String> channels)
     {
-        ChannelComboBox channelChooser =
-                new ChannelComboBox(channels, defaultChannelState, basicImageChannelCode);
+        final ChannelChooserPanel channelChooser =
+                new ChannelChooserPanel(defaultChannelState, channels, basicChannelCodes);
+
         channelChooser
-                .addSelectionChangedListener(new SelectionChangedListener<SimpleComboValue<String>>()
+                .setSelectionChangedListener(new ChannelChooserPanel.ChannelSelectionListener()
                     {
-                        @Override
-                        public void selectionChanged(
-                                SelectionChangedEvent<SimpleComboValue<String>> se)
+                        public void selectionChanged(List<String> newlySelectedChannels)
                         {
-                            String selectedChannelCode = se.getSelectedItem().getValue();
-                            basicImageChannelCode = selectedChannelCode;
+                            basicChannelCodes = newlySelectedChannels;
                             refresh();
                         }
                     });
+
         return GuiUtils.withLabel(channelChooser, CHANNEL_MSG);
     }
 
-    private static String getInitialChannelCode(IDefaultChannelState defaultChannelState,
+    private static List<String> getInitialChannelCodes(IDefaultChannelState defaultChannelState,
             List<String> channels)
     {
-        String initialChannel = defaultChannelState.tryGetDefaultChannel();
-        if (initialChannel == null || channels.indexOf(initialChannel) == -1)
+        List<String> defaultChannels = defaultChannelState.tryGetDefaultChannels();
+        if (defaultChannels == null || false == channels.containsAll(defaultChannels))
         {
-            initialChannel =
-                    channels.size() > 1 ? ScreeningConstants.MERGED_CHANNELS : channels.get(0);
+            return channels;
         }
-        return initialChannel;
+        return defaultChannels;
     }
 
 }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooserPanel.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooserPanel.java
new file mode 100644
index 00000000000..67491022171
--- /dev/null
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelChooserPanel.java
@@ -0,0 +1,296 @@
+/*
+ * 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.plugin.screening.client.web.client.application.detailviewers;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+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.CheckBox;
+import com.extjs.gxt.ui.client.widget.form.CheckBoxGroup;
+import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
+import com.extjs.gxt.ui.client.widget.form.Field;
+import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
+
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants;
+
+/**
+ * An UI panel for selecting image channels.
+ * 
+ * @author Kaloyan Enimanev
+ */
+public class ChannelChooserPanel extends LayoutContainer
+{
+
+    /**
+     * Can be used from external classes wishing to be notified when the channel selection changes.
+     */
+    public static interface ChannelSelectionListener
+    {
+        void selectionChanged(List<String> channels);
+    }
+
+    private IDefaultChannelState defaultChannelState;
+
+    private CheckBoxGroup channelsCheckBoxGroup;
+
+    private SimpleComboBox<String> channelsComboBox;
+
+    private ChannelSelectionListener channelSelectionListener;
+
+    private final Listener<BaseEvent> selectionChangeListener = new Listener<BaseEvent>()
+        {
+
+        public void handleEvent(BaseEvent be)
+            {
+                selectionChanged();
+            }
+
+        };
+
+    public ChannelChooserPanel(IDefaultChannelState defChannelState)
+    {
+        this(defChannelState, Collections.<String> emptyList(), Collections.<String> emptyList());
+    }
+
+    public ChannelChooserPanel(IDefaultChannelState defChannelState, List<String> names,
+            List<String> selectedChannelsOrNull)
+    {
+        this.defaultChannelState = defChannelState;
+
+        setAutoHeight(true);
+        setAutoWidth(true);
+
+        channelsComboBox = createChannelsComboBox();
+        add(channelsComboBox);
+
+        channelsCheckBoxGroup = new CheckBoxGroup();
+        add(channelsCheckBoxGroup);
+
+        initializeAvailableChannels(names);
+        initializeChannelSelection(selectedChannelsOrNull);
+    }
+
+    private SimpleComboBox<String> createChannelsComboBox()
+    {
+        SimpleComboBox<String> comboBox = new SimpleComboBox<String>();
+
+        comboBox.setTriggerAction(TriggerAction.ALL);
+        comboBox.setAllowBlank(false);
+        comboBox.setEditable(false);
+        comboBox.setEmptyText("Choose...");
+        comboBox.addListener(Events.SelectionChange, selectionChangeListener);
+
+        return comboBox;
+    }
+
+    /**
+     * sets a {@link ChannelSelectionListener} that will be receiving notifications when the
+     * selection changes.
+     */
+    public void setSelectionChangedListener(ChannelSelectionListener selectionListener)
+    {
+        this.channelSelectionListener = selectionListener;
+    }
+
+    /**
+     * a quite specific method, currently only needed by the well-search grid.
+     */
+    public void initializeCodesForWellSearchGrid(List<String> codes)
+    {
+        initializeAvailableChannels(codes);
+        initializeChannelSelection(null);
+    }
+
+    /**
+     * @return the current channel selection. If all channels are selected, returns a list
+     *         containing a single element - {@link ScreeningConstants#MERGED_CHANNELS}.
+     */
+    public List<String> getSelectedValues()
+    {
+        String comboBoxValue = channelsComboBox.getSimpleValue();
+        if (comboBoxValue == null)
+        {
+            return Collections.<String> emptyList();
+        }
+        if (ScreeningConstants.MERGED_CHANNELS.equals(comboBoxValue))
+        {
+            // multiple channel selection
+            return getMergedChannelSelection();
+        } else
+        {
+            // single channel selection
+            return Collections.singletonList(comboBoxValue);
+        }
+    }
+
+    private List<String> getMergedChannelSelection()
+    {
+        boolean allSelected = true;
+        List<String> channels = new ArrayList<String>();
+        for (CheckBox cb : getAllCheckBoxes())
+        {
+            if (cb.getValue() == true)
+            {
+                channels.add(cb.getBoxLabel());
+            } else
+            {
+                allSelected = false;
+            }
+        }
+
+        if (allSelected)
+        {
+            // all channels selected
+            // do not list them one-by-one. use the more general "MERGED_CHANNELS" term instead
+            return Collections.singletonList(ScreeningConstants.MERGED_CHANNELS);
+        }
+        return channels;
+    }
+    
+    private void initializeAvailableChannels(List<String> codes)
+    {
+        addCodeToComboBox(ScreeningConstants.MERGED_CHANNELS);
+        if (codes == null || codes.isEmpty())
+        {
+            return;
+        }
+
+        for (String code : codes)
+        {
+            if (addCodeToComboBox(code))
+            {
+                // also add a checkBockbox for the channel
+                CheckBox checkBox = new CheckBox();
+                checkBox.setBoxLabel(code);
+                checkBox.addListener(Events.Change, selectionChangeListener);
+                channelsCheckBoxGroup.add(checkBox);
+            }
+        }
+    }
+    
+    private boolean addCodeToComboBox(String code)
+    {
+        if (channelsComboBox.findModel(code) == null)
+        {
+            channelsComboBox.add(code);
+            return true;
+        }
+        return false;
+    }
+    
+    private void initializeChannelSelection(List<String> selectedChannels)
+    {
+        List<String> channels = selectedChannels;
+        if (channels == null || channels.size() == 0)
+        {
+            if (defaultChannelState != null)
+            {
+                channels = defaultChannelState.tryGetDefaultChannels();
+            }
+        }
+
+        String comboBoxValue = ScreeningConstants.MERGED_CHANNELS;
+        if (channels != null && channels.size() == 1)
+        {
+            comboBoxValue = channels.get(0);
+        }
+        
+        channelsComboBox.setSimpleValue(comboBoxValue);
+
+        initializeCheckBoxValues(channels);
+    }
+
+    private void initializeCheckBoxValues(List<String> selectedChannels)
+    {
+        boolean selectAllChannels = (selectedChannels == null) || (selectedChannels.size() < 2);
+
+        for (CheckBox cb : getAllCheckBoxes())
+        {
+            @SuppressWarnings("null")
+            boolean checked = selectAllChannels || selectedChannels.contains(cb.getBoxLabel());
+            cb.setValue(checked);
+        }
+
+    }
+
+    private void selectionChanged()
+    {
+        List<String> selection = getSelectedValues();
+        defaultChannelState.setDefaultChannels(selection);
+
+        String selectedComboValue = channelsComboBox.getSimpleValue();
+        boolean showCheckBoxGroup = ScreeningConstants.MERGED_CHANNELS.equals(selectedComboValue);
+        ensureAtLeastOneCheckboxChecked();
+        channelsCheckBoxGroup.setVisible(showCheckBoxGroup);
+
+        if (channelSelectionListener != null)
+        {
+            channelSelectionListener.selectionChanged(selection);
+        }
+    }
+
+    private void ensureAtLeastOneCheckboxChecked()
+    {
+        List<CheckBox> checkboxes = getAllCheckBoxes();
+        int selected = 0;
+
+        for (CheckBox cb : checkboxes)
+        {
+            if (cb.getValue())
+            {
+                selected++;
+            }
+        }
+
+        if (selected > 1)
+        {
+            for (CheckBox cb : checkboxes)
+            {
+                cb.setEnabled(true);
+            }
+        } else
+        {
+            for (CheckBox cb : checkboxes)
+            {
+                if (cb.getValue())
+                {
+                    cb.setEnabled(false);
+                }
+            }
+        }
+
+    }
+
+
+    private List<CheckBox> getAllCheckBoxes()
+    {
+        List<CheckBox> result = new ArrayList<CheckBox>();
+        for (Field<?> field : channelsCheckBoxGroup.getAll())
+        {
+            if (field instanceof CheckBox)
+            {
+                result.add((CheckBox) field);
+            }
+        }
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelComboBox.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelComboBox.java
deleted file mode 100644
index eb1619990d8..00000000000
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelComboBox.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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.plugin.screening.client.web.client.application.detailviewers;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
-import com.extjs.gxt.ui.client.event.SelectionChangedListener;
-import com.extjs.gxt.ui.client.widget.form.SimpleComboBox;
-import com.extjs.gxt.ui.client.widget.form.SimpleComboValue;
-
-import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ScreeningConstants;
-
-/**
- * Combobox storing channel names.
- * 
- * @author Izabela Adamczyk
- */
-public class ChannelComboBox extends SimpleComboBox<String>
-{
-
-    private IDefaultChannelState defaultChannelState;
-
-    /**
-     * Creates empty {@link ChannelComboBox}.
-     */
-    public ChannelComboBox(final IDefaultChannelState defaultChannelState)
-    {
-        setTriggerAction(TriggerAction.ALL);
-        setAllowBlank(false);
-        setEditable(false);
-        setEmptyText("Choose...");
-        this.defaultChannelState = defaultChannelState;
-        addSelectionChangedListener(new SelectionChangedListener<SimpleComboValue<String>>()
-            {
-                @Override
-                public void selectionChanged(SelectionChangedEvent<SimpleComboValue<String>> se)
-                {
-                    String selectedValueOrNull = se.getSelectedItem().getValue();
-                    if (selectedValueOrNull != null)
-                    {
-                        defaultChannelState.setDefaultChannel(selectedValueOrNull);
-                    }
-                }
-            });
-    }
-
-    /**
-     * Creates {@link ChannelComboBox} with initial list of values and selects given initial value.
-     */
-    public ChannelComboBox(List<String> names, IDefaultChannelState defaultChannelState,
-            String selectedChannelOrNull)
-    {
-        this(defaultChannelState);
-        addUniqueCodes(names);
-        if (selectedChannelOrNull == null)
-        {
-            autoselect();
-        } else
-        {
-            setSimpleValue(selectedChannelOrNull);
-        }
-    }
-
-    /**
-     * Selects default channel if such an information was saved before. Otherwise first element if
-     * nothing was selected before.
-     */
-    private void autoselect()
-    {
-        if (getStore().getModels().size() > 0 && getValue() == null)
-        {
-            if (defaultChannelState != null && defaultChannelState.tryGetDefaultChannel() != null)
-            {
-                setSimpleValue(defaultChannelState.tryGetDefaultChannel());
-            } else
-            {
-                setValue(getStore().getModels().get(0));
-            }
-        }
-    }
-
-    /**
-     * Adds names to the combo box if they were not yet present.
-     */
-    private void addUniqueCodes(List<String> codes)
-    {
-        List<String> withMerged = new ArrayList<String>();
-        withMerged.add(ScreeningConstants.MERGED_CHANNELS);
-        withMerged.addAll(codes);
-        for (String s : withMerged)
-        {
-            if (findModel(s) == null)
-            {
-                add(s);
-            }
-        }
-    }
-
-    public void addCodesAndListener(List<String> newCodes,
-            SelectionChangedListener<SimpleComboValue<String>> listener)
-    {
-        addUniqueCodes(newCodes);
-        addSelectionChangedListener(listener);
-        autoselect();
-    }
-
-}
\ No newline at end of file
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelWidgetWithListener.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelWidgetWithListener.java
index b2b12e46f42..ca23453a81e 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelWidgetWithListener.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ChannelWidgetWithListener.java
@@ -16,22 +16,20 @@
 
 package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers;
 
-import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
-import com.extjs.gxt.ui.client.event.SelectionChangedListener;
+import java.util.List;
+
 import com.extjs.gxt.ui.client.widget.LayoutContainer;
-import com.extjs.gxt.ui.client.widget.form.SimpleComboValue;
 import com.google.gwt.user.client.ui.Widget;
 
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.utils.GuiUtils;
 
 /**
  * Allows to create a {@link Widget} ({@link #asWidget()}) containing channel view and allows to
- * manually update visible channel ({@link #update(String)}) or create a listener that can be added
- * to channel selector.
+ * manually update visible channel via the ({@link #selectionChanged(List)}) method.
  * 
  * @author Izabela Adamczyk
  */
-public class ChannelWidgetWithListener
+public class ChannelWidgetWithListener implements ChannelChooserPanel.ChannelSelectionListener
 {
     final private LayoutContainer container;
 
@@ -39,7 +37,7 @@ public class ChannelWidgetWithListener
 
     interface ISimpleChanneledViewerFactory
     {
-        Widget create(String channelCode);
+        Widget create(List<String> channelCodes);
     }
 
     public ChannelWidgetWithListener(final ISimpleChanneledViewerFactory viewerFactory)
@@ -48,30 +46,16 @@ public class ChannelWidgetWithListener
         this.viewerFactory = viewerFactory;
     }
 
-    public void update(String channelName)
-    {
-        if (channelName != null)
-        {
-            GuiUtils.replaceLastItem(container, viewerFactory.create(channelName));
-        }
-    }
-
-    public SelectionChangedListener<SimpleComboValue<String>> asSelectionChangedListener()
+    public Widget asWidget()
     {
-        return new SelectionChangedListener<SimpleComboValue<String>>()
-            {
-
-                @Override
-                public void selectionChanged(SelectionChangedEvent<SimpleComboValue<String>> se)
-                {
-                    update(se.getSelectedItem().getValue());
-                }
-
-            };
+        return container;
     }
 
-    public Widget asWidget()
+    public void selectionChanged(List<String> channelNames)
     {
-        return container;
+        if (channelNames != null)
+        {
+            GuiUtils.replaceLastItem(container, viewerFactory.create(channelNames));
+        }
     }
 }
\ No newline at end of file
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/DefaultChannelState.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/DefaultChannelState.java
new file mode 100644
index 00000000000..a8fc04d3496
--- /dev/null
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/DefaultChannelState.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2011 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers;
+
+import java.util.List;
+
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningDisplaySettingsManager;
+import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningViewContext;
+
+/**
+ * @author Kaloyan Enimanev
+ */
+public class DefaultChannelState implements IDefaultChannelState
+{
+    private IViewContext<?> viewContext;
+
+    private String displayTypeId;
+
+    public DefaultChannelState(IViewContext<?> viewContext, String displayTypeId)
+    {
+        this.viewContext = viewContext;
+        this.displayTypeId = displayTypeId;
+    }
+
+    public void setDefaultChannels(List<String> channels)
+    {
+        getDisplaySettingManager().setDefaultChannels(displayTypeId, channels);
+    }
+
+    public List<String> tryGetDefaultChannels()
+    {
+        return getDisplaySettingManager().tryGetDefaultChannels(displayTypeId);
+    }
+
+    private ScreeningDisplaySettingsManager getDisplaySettingManager()
+    {
+        return ScreeningViewContext.getTechnologySpecificDisplaySettingsManager(viewContext);
+    }
+
+}
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/IDefaultChannelState.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/IDefaultChannelState.java
index 2c5a07eca70..3c0187b92b0 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/IDefaultChannelState.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/IDefaultChannelState.java
@@ -1,14 +1,15 @@
 package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers;
 
+import java.util.List;
 
 /**
- * Allows to get and set the channel which is chosen by default when images are shown in a specific context.
- *  
+ * Allows to get and set the channels chosen by default when images are shown in a specific context.
+ * 
  * @author Piotr Buczek
  */
 public interface IDefaultChannelState
 {
-    public String tryGetDefaultChannel();
+    public List<String> tryGetDefaultChannels();
 
-    public void setDefaultChannel(String value);
+    public void setDefaultChannels(List<String> channels);
 }
\ No newline at end of file
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ImageUrlUtils.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ImageUrlUtils.java
index 7cb55f49df4..0a59a46bf1d 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ImageUrlUtils.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/ImageUrlUtils.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers;
 
+import java.util.List;
 import java.util.Set;
 
 import com.extjs.gxt.ui.client.widget.Component;
@@ -139,12 +140,20 @@ public class ImageUrlUtils
             LogicalImageChannelsReference channelReferences)
     {
         LogicalImageReference images = channelReferences.getBasicImage();
-        String signature =
-                images.getTransformerFactorySignatureOrNull(channelReferences
-                        .getBasicImageChannelCode());
-        if (signature != null)
+
+        // TODO KE: Tomek, should we add a "transformerFactorySignature" for each selected channel ?
+        List<String> channels = channelReferences.getChannelCodes();
+        if (channels != null)
         {
-            url.addParameter("transformerFactorySignature", signature);
+            for (String channel : channels)
+            {
+                String signature = images.getTransformerFactorySignatureOrNull(channel);
+                if (signature != null)
+                {
+                    url.addParameter("transformerFactorySignature", signature);
+                }
+
+            }
         }
     }
 
@@ -158,15 +167,21 @@ public class ImageUrlUtils
         methodWithParameters.addParameter("sessionID", sessionID);
         methodWithParameters.addParameter(ImageServletUrlParameters.DATASET_CODE_PARAM,
                 images.getDatasetCode());
-        String channel = channelReferences.getBasicImageChannelCode();
-        if (channel.equals(ScreeningConstants.MERGED_CHANNELS))
+
+        List<String> channels = channelReferences.getChannelCodes();
+        if (channels.contains(ScreeningConstants.MERGED_CHANNELS))
         {
             methodWithParameters.addParameter(ImageServletUrlParameters.MERGE_CHANNELS_PARAM,
                     "true");
         } else
         {
-            methodWithParameters.addParameter(ImageServletUrlParameters.CHANNEL_PARAM, channel);
+            for (String channel : channelReferences.getChannelCodes())
+            {
+                methodWithParameters.addParameter(ImageServletUrlParameters.CHANNEL_PARAM, channel);
+            }
         }
+                
+
         addOverlayParameters(channelReferences.getOverlayChannels(), methodWithParameters);
         return methodWithParameters;
     }
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/LogicalImageViewer.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/LogicalImageViewer.java
index 8739f887b79..b67742b7133 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/LogicalImageViewer.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/LogicalImageViewer.java
@@ -18,24 +18,6 @@ package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.
 
 import java.util.List;
 
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
-import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
-import ch.systemsx.cisd.openbis.generic.shared.basic.URLMethodWithParameters;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.IScreeningClientServiceAsync;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.ParameterNames;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.Constants;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.Dict;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningDisplaySettingsManager;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningDisplayTypeIDGenerator;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningViewContext;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.ChannelChooser.IChanneledViewerFactory;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.dto.LogicalImageChannelsReference;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.dto.LogicalImageReference;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannelStack;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetEnrichedReference;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.LogicalImageInfo;
-import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
-
 import com.extjs.gxt.ui.client.Style.Scroll;
 import com.extjs.gxt.ui.client.event.ButtonEvent;
 import com.extjs.gxt.ui.client.event.SelectionListener;
@@ -52,6 +34,22 @@ import com.google.gwt.core.client.GWT;
 import com.google.gwt.user.client.Window;
 import com.google.gwt.user.client.ui.Widget;
 
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.AbstractAsyncCallback;
+import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext;
+import ch.systemsx.cisd.openbis.generic.shared.basic.URLMethodWithParameters;
+import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.IScreeningClientServiceAsync;
+import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.ParameterNames;
+import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.Constants;
+import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.Dict;
+import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningDisplayTypeIDGenerator;
+import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.ChannelChooser.IChanneledViewerFactory;
+import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.dto.LogicalImageChannelsReference;
+import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.dto.LogicalImageReference;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageChannelStack;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.ImageDatasetEnrichedReference;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.LogicalImageInfo;
+import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.WellLocation;
+
 /**
  * A widget which displays one logical image pointed by {@link LogicalImageReference}.
  * 
@@ -81,7 +79,7 @@ public class LogicalImageViewer
 
     private final boolean showColorAdjustmentButton;
 
-    private String currentlySelectedChannelCode;
+    private List<String> currentlySelectedChannelCodes;
 
     public LogicalImageViewer(LogicalImageReference logicalImageReference,
             IViewContext<IScreeningClientServiceAsync> viewContext, String experimentIdentifier,
@@ -173,7 +171,7 @@ public class LogicalImageViewer
             {
                 public LayoutContainer create(LogicalImageChannelsReference channelReferences)
                 {
-                    currentlySelectedChannelCode = channelReferences.getBasicImageChannelCode();
+                    currentlySelectedChannelCodes = channelReferences.getChannelCodes();
                     String sessionId = getSessionId(viewContext);
                     int imageWidth = getImageWidth(logicalImageReference);
                     int imageHeight = getImageHeight(logicalImageReference);
@@ -277,7 +275,7 @@ public class LogicalImageViewer
             {
                 public LayoutContainer create(LogicalImageChannelsReference channelReferences)
                 {
-                    currentlySelectedChannelCode = channelReferences.getBasicImageChannelCode();
+                    currentlySelectedChannelCodes = channelReferences.getChannelCodes();
                     String sessionId = getSessionId(viewContext);
                     return createTilesGrid(channelReferences, sessionId);
                 }
@@ -288,24 +286,11 @@ public class LogicalImageViewer
     private static IDefaultChannelState createDefaultChannelState(
             final IViewContext<?> viewContext, final String experimentPermId)
     {
-        final ScreeningDisplaySettingsManager screeningDisplaySettingManager =
-                ScreeningViewContext.getTechnologySpecificDisplaySettingsManager(viewContext);
         final ScreeningDisplayTypeIDGenerator wellSearchChannelIdGenerator =
                 ScreeningDisplayTypeIDGenerator.EXPERIMENT_CHANNEL;
         final String displayTypeID = wellSearchChannelIdGenerator.createID(experimentPermId);
 
-        return new IDefaultChannelState()
-            {
-                public void setDefaultChannel(String channel)
-                {
-                    screeningDisplaySettingManager.setDefaultChannel(displayTypeID, channel);
-                }
-
-                public String tryGetDefaultChannel()
-                {
-                    return screeningDisplaySettingManager.tryGetDefaultChannel(displayTypeID);
-                }
-            };
+        return new DefaultChannelState(viewContext, displayTypeID);
     }
 
     /** Launches external image editor for the displayed image in the chosen channel. */
@@ -318,9 +303,10 @@ public class LogicalImageViewer
         urlParams.addParameter(ParameterNames.SERVER_URL, GWT.getHostPageBaseURL());
         urlParams.addParameter(ParameterNames.EXPERIMENT_ID, experimentIdentifier);
 
-        if (currentlySelectedChannelCode != null)
+        // TODO KE: How do we support the launching of ImageViewer with channel parameters ?
+        if (currentlySelectedChannelCodes != null)
         {
-            urlParams.addParameter(ParameterNames.CHANNEL, currentlySelectedChannelCode);
+            urlParams.addParameter(ParameterNames.CHANNEL, currentlySelectedChannelCodes);
         }
         WellLocation wellLocation = logicalImageReference.tryGetWellLocation();
         if (wellLocation != null)
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellContentDialog.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellContentDialog.java
index b461ca71e60..d5b52ef4b0b 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellContentDialog.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellContentDialog.java
@@ -129,13 +129,15 @@ public class WellContentDialog extends Dialog
     }
 
     /**
-     * Creates a view for the specified channel.
+     * Creates a view for the specified channels.
      * 
-     * @param channel Channel numbers start with 1. Channel 0 consists of all other channels merged.
+     * @param channels the channel names. If "MERGED_CHANNELS" is specified, there must be no other
+     *            channel elements present.
      */
     public static Widget createImageViewerForChannel(
             final IViewContext<IScreeningClientServiceAsync> viewContext,
-            final WellContent wellContent, int imageWidthPx, int imageHeightPx, String channel)
+            final WellContent wellContent, int imageWidthPx, int imageHeightPx,
+            List<String> channels)
     {
         final ImageDatasetEnrichedReference imageDataset = tryGetImageDataset(wellContent);
         if (imageDataset == null)
@@ -148,8 +150,8 @@ public class WellContentDialog extends Dialog
             return new Text(INCORRECT_WELL_CODE_LABEL);
         }
         ImageDatasetParameters imageParameters = imageDataset.getImageDatasetParameters();
-        if (imageParameters.getChannelsCodes().contains(channel) == false
-                && channel.equals(ScreeningConstants.MERGED_CHANNELS) == false)
+        if (imageParameters.getChannelsCodes().containsAll(channels) == false
+                && channels.contains(ScreeningConstants.MERGED_CHANNELS) == false)
         {
             return new Text(UNKNOWN_CHANNEL_LABEL);
         }
@@ -159,7 +161,7 @@ public class WellContentDialog extends Dialog
         final LogicalImageReference wellImages =
                 new LogicalImageReference(imageDataset, locationOrNull);
         LogicalImageChannelsReference channelReferences =
-                LogicalImageChannelsReference.createWithoutOverlays(wellImages, channel);
+                LogicalImageChannelsReference.createWithoutOverlays(wellImages, channels);
         LayoutContainer staticTilesGrid =
                 LogicalImageViewer.createTilesGrid(channelReferences, sessionId, imageWidthPx,
                         imageHeightPx, createImageLinks);
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellSearchGrid.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellSearchGrid.java
index 1dad1cd192f..0e4153aa1a8 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellSearchGrid.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/WellSearchGrid.java
@@ -76,9 +76,7 @@ import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.IScreeningCli
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ClientPluginFactory;
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.Dict;
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.DisplayTypeIDGenerator;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningDisplaySettingsManager;
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningDisplayTypeIDGenerator;
-import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ScreeningViewContext;
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.ChannelWidgetWithListener.ISimpleChanneledViewerFactory;
 import ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.ui.columns.specific.ScreeningLinkExtractor;
 import ch.systemsx.cisd.openbis.plugin.screening.shared.basic.dto.DatasetImagesReference;
@@ -247,7 +245,7 @@ public class WellSearchGrid extends TypedTableGrid<WellContent>
 
     private SingleExperimentSearchCriteria singleExperimentChooserStateOrNull;
 
-    private ChannelComboBox channelChooser;
+    private ChannelChooserPanel channelChooser;
 
     private WellSearchGrid(IViewContext<IScreeningClientServiceAsync> viewContext,
             ExperimentSearchCriteria experimentCriteriaOrNull,
@@ -261,7 +259,7 @@ public class WellSearchGrid extends TypedTableGrid<WellContent>
 
         final IDefaultChannelState defaultChannelState =
                 createDefaultChannelState(viewContext, experimentCriteriaOrNull);
-        channelChooser = new ChannelComboBox(defaultChannelState);
+        channelChooser = new ChannelChooserPanel(defaultChannelState);
         linkWellContent();
         linkExperiment();
         linkPlate();
@@ -274,35 +272,21 @@ public class WellSearchGrid extends TypedTableGrid<WellContent>
             final IViewContext<IScreeningClientServiceAsync> viewContext,
             ExperimentSearchCriteria experimentCriteriaOrNull)
     {
-        final ScreeningDisplaySettingsManager screeningDisplaySettingManager =
-                ScreeningViewContext.getTechnologySpecificDisplaySettingsManager(viewContext);
-
         // If there is a single experiment set in criteria reuse default channel settings,
         // otherwise use global settings.
-        final ScreeningDisplayTypeIDGenerator displayTypeIdGenerator =
+        ScreeningDisplayTypeIDGenerator displayTypeIdGenerator =
                 ScreeningDisplayTypeIDGenerator.EXPERIMENT_CHANNEL;
-        final String displayTypeId;
+        String displayTypeId;
         if (experimentCriteriaOrNull != null && experimentCriteriaOrNull.tryGetExperiment() != null)
         {
-            final String experimentPermId =
+            String experimentPermId =
                     experimentCriteriaOrNull.tryGetExperiment().getExperimentPermId();
             displayTypeId = displayTypeIdGenerator.createID(experimentPermId);
         } else
         {
             displayTypeId = displayTypeIdGenerator.createID(null);
         }
-        return new IDefaultChannelState()
-            {
-                public void setDefaultChannel(String channel)
-                {
-                    screeningDisplaySettingManager.setDefaultChannel(displayTypeId, channel);
-                }
-
-                public String tryGetDefaultChannel()
-                {
-                    return screeningDisplaySettingManager.tryGetDefaultChannel(displayTypeId);
-                }
-            };
+        return new DefaultChannelState(viewContext, displayTypeId);
     }
 
     private void linkWellContent()
@@ -630,23 +614,23 @@ public class WellSearchGrid extends TypedTableGrid<WellContent>
                     {
                         return null;
                     }
-                    ImageDatasetParameters imageParameters = images.getImageParameters();
                     final ISimpleChanneledViewerFactory viewerFactory =
                             new ISimpleChanneledViewerFactory()
                                 {
-                                    public Widget create(String channel)
+                                    public Widget create(List<String> channels)
                                     {
                                         return WellContentDialog.createImageViewerForChannel(
                                                 viewContext, entity, IMAGE_WIDTH_PX,
-                                                IMAGE_HEIGHT_PX, channel);
+                                                IMAGE_HEIGHT_PX, channels);
                                     }
                                 };
                     ChannelWidgetWithListener widgetWithListener =
                             new ChannelWidgetWithListener(viewerFactory);
-                    widgetWithListener.update(channelChooser.getSimpleValue());
 
-                    channelChooser.addCodesAndListener(imageParameters.getChannelsCodes(),
-                            widgetWithListener.asSelectionChangedListener());
+                    ImageDatasetParameters imageParameters = images.getImageParameters();
+                    channelChooser.setSelectionChangedListener(widgetWithListener);
+                    channelChooser.initializeCodesForWellSearchGrid(imageParameters.getChannelsCodes());
+
                     return widgetWithListener.asWidget();
                 }
 
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/dto/LogicalImageChannelsReference.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/dto/LogicalImageChannelsReference.java
index e042e005aec..56dbab0bdc8 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/dto/LogicalImageChannelsReference.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/web/client/application/detailviewers/dto/LogicalImageChannelsReference.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.openbis.plugin.screening.client.web.client.application.detailviewers.dto;
 
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -27,9 +28,9 @@ import java.util.Set;
 public class LogicalImageChannelsReference
 {
     public static LogicalImageChannelsReference createWithoutOverlays(
-            LogicalImageReference basicImage, String channel)
+            LogicalImageReference basicImage, List<String> channels)
     {
-        return new LogicalImageChannelsReference(basicImage, channel,
+        return new LogicalImageChannelsReference(basicImage, channels,
                 new HashSet<ImageDatasetChannel>());
     }
 
@@ -37,15 +38,15 @@ public class LogicalImageChannelsReference
     
     private final LogicalImageReference basicImage;
 
-    private final String channel;
+    private final List<String> channels;
 
     private final Set<ImageDatasetChannel> overlayChannels;
 
-    public LogicalImageChannelsReference(LogicalImageReference basicImage, String channel,
+    public LogicalImageChannelsReference(LogicalImageReference basicImage, List<String> channels,
             Set<ImageDatasetChannel> overlayChannels)
     {
         this.basicImage = basicImage;
-        this.channel = channel;
+        this.channels = channels;
         this.overlayChannels = overlayChannels;
     }
 
@@ -54,9 +55,9 @@ public class LogicalImageChannelsReference
         return basicImage;
     }
 
-    public String getBasicImageChannelCode()
+    public List<String> getChannelCodes()
     {
-        return channel;
+        return channels;
     }
 
     public Set<ImageDatasetChannel> getOverlayChannels()
-- 
GitLab