diff --git a/common/source/java/ch/systemsx/cisd/common/color/HSBColor.java b/common/source/java/ch/systemsx/cisd/common/color/HSBColor.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b01f938efcdb6f8972d7bbc26186f7fff8e6f99
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/color/HSBColor.java
@@ -0,0 +1,153 @@
+/*
+ * 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.common.color;
+
+import java.awt.Color;
+
+/**
+ * A color object in the HSB (Hue, Saturation, Brightness) color space. 
+ * 
+ * @author Bernd Rinn
+ */
+public class HSBColor
+{
+    private final float hue;
+
+    private final float saturation;
+
+    private final float brightness;
+
+    /**
+     * Constructs an HSBColor from the given {@link java.awt.Color}. 
+     */
+    public static HSBColor createFromRGBColor(Color color)
+    {
+        float[] hsv = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
+        return new HSBColor(hsv[0], hsv[1], hsv[2]);
+    }
+
+    /**
+     * Constructor for a pure bright color (saturation = 1, brightness = 1).
+     * 
+     * @param hue The color's hue.
+     */
+    public HSBColor(float hue)
+    {
+        this(hue, 1.0f, 1.0f);
+    }
+
+    /**
+     * Constructor for a pure color (saturation = 1).
+     * 
+     * @param hue The color's hue.
+     * @param brightness The color's brightness.
+     */
+    public HSBColor(float hue, float brightness)
+    {
+        this(hue, 1.0f, brightness);
+    }
+
+    /**
+     * Constructor for an arbitrary color.
+     * 
+     * @param hue The color's hue.
+     * @param saturation The color's saturation.
+     * @param brightness The color's brightness.
+     */
+    public HSBColor(float hue, float saturation, float brightness)
+    {
+        this.hue = hue;
+        this.saturation = saturation;
+        this.brightness = brightness;
+    }
+
+    /**
+     * Returns the color's hue.
+     * 
+     * @return The hue normalized to 1; in the range [0,1)
+     */
+    public float getHue()
+    {
+        return hue;
+    }
+
+    /**
+     * Returns the color's hue.
+     * 
+     * @return The hue in degree; in the range [0,360)
+     */
+    public float getHueDegree()
+    {
+        return hue * 360f;
+    }
+
+    /**
+     * Returns the color's saturation.
+     * 
+     * @return The saturation; in the range [0,1]
+     */
+    public float getSaturation()
+    {
+        return saturation;
+    }
+
+    /**
+     * Returns the color's brightness.
+     * 
+     * @return The brightness; in the range [0,1]
+     */
+    public float getBrightness()
+    {
+        return brightness;
+    }
+
+    /**
+     * Returns <code>true</code>, if the color is <i>pure</i>, that is: has a saturation of 1.0.
+     */
+    public boolean isPure()
+    {
+        return saturation == 1.0f;
+    }
+
+    /**
+     * Creates a pure color with the same hue and brightness as this color.
+     * 
+     * @return The pure color.
+     */
+    public HSBColor createPureColor()
+    {
+        return new HSBColor(hue, brightness);
+    }
+
+    /**
+     * Creates a pure bright color with the same hue as this color.
+     * 
+     * @return The pure bright color.
+     */
+    public HSBColor createPureBrightColor()
+    {
+        return new HSBColor(hue);
+    }
+
+    /**
+     * Returns an {@link java.awt.Color} from this color.
+     */
+    public Color getColor()
+    {
+        return Color.getHSBColor(hue, saturation, brightness);
+    }
+}
diff --git a/common/source/java/ch/systemsx/cisd/common/color/MixColors.java b/common/source/java/ch/systemsx/cisd/common/color/MixColors.java
new file mode 100644
index 0000000000000000000000000000000000000000..343b609bbeae765b49d9265b7d552c47af27cac8
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/color/MixColors.java
@@ -0,0 +1,72 @@
+/*
+ * 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.common.color;
+
+/**
+ * A class for calculating a mixed color from a set of pure colors of different relative
+ * intensities.
+ * <p>
+ * It uses an additive (physiological) color mixture.
+ * 
+ * @author Bernd Rinn
+ */
+public class MixColors
+{
+
+    private static float[] calcWeights(PureHSBColor[] colors, float[] intensities)
+    {
+        final float[] effectiveIntensities = new float[intensities.length];
+        float sum = 0.0f;
+        for (int i = 0; i < intensities.length; ++i)
+        {
+            effectiveIntensities[i] = intensities[i] * colors[i].getBrightness();
+            sum += effectiveIntensities[i];
+        }
+        final float[] weights = new float[intensities.length];
+        for (int i = 0; i < intensities.length; ++i)
+        {
+            weights[i] = effectiveIntensities[i] / sum;
+        }
+        return weights;
+    }
+
+    /**
+     * Calculates a mixed color from given pure <var>colors</var>.
+     * 
+     * @param colors The colors to mix.
+     * @param intensities The intensities of each color. Has to be the same length as
+     *            <var>colors</var>.
+     * @return The mixed color.
+     */
+    public static PureHSBColor calcMixedColor(PureHSBColor[] colors, float[] intensities)
+    {
+        assert colors.length == intensities.length;
+
+        final float[] weights = calcWeights(colors, intensities);
+
+        float hue = 0.0f;
+        float brightness = 0.0f;
+        for (int i = 0; i < weights.length; ++i)
+        {
+            hue += weights[i] * colors[i].getHue();
+            brightness = Math.max(brightness, colors[i].getBrightness());
+        }
+
+        return new PureHSBColor(hue, brightness);
+    }
+
+}
diff --git a/common/source/java/ch/systemsx/cisd/common/color/PureHSBColor.java b/common/source/java/ch/systemsx/cisd/common/color/PureHSBColor.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ebc326d04e4f9158eee0d1025e56a6cf176d7aa
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/color/PureHSBColor.java
@@ -0,0 +1,56 @@
+/*
+ * 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.common.color;
+
+import java.awt.Color;
+
+/**
+ * A pure color object in the HSB (Hue, Saturation, Brightness) color space.
+ * <p>
+ * A pure color is defined by having saturation = 1.0. 
+ * 
+ * @author Bernd Rinn
+ */
+public class PureHSBColor extends HSBColor
+{
+    /**
+     * Constructs a PureHSBColor from the given {@link java.awt.Color}. 
+     * 
+     * @throw {@link IllegalArgumentException} if <var>color</var> is not pure.
+     */
+    public static PureHSBColor createFromRGBColor(Color color) throws IllegalArgumentException
+    {
+        float[] hsv = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
+        if (hsv[1] != 1.0f)
+        {
+            throw new IllegalArgumentException("Not a pure color: " + color);
+        }
+        return new PureHSBColor(hsv[0], hsv[2]);
+    }
+
+    public PureHSBColor(float hue, float brightness)
+    {
+        super(hue, 1.0f, brightness);
+    }
+
+    @Override
+    public boolean isPure()
+    {
+        return true;
+    }
+
+}
diff --git a/common/source/java/ch/systemsx/cisd/common/color/WavelengthColor.java b/common/source/java/ch/systemsx/cisd/common/color/WavelengthColor.java
new file mode 100644
index 0000000000000000000000000000000000000000..77e58409596d2f9b2f283d8d48fdb38d89d8ba66
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/color/WavelengthColor.java
@@ -0,0 +1,157 @@
+/*
+ * 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.common.color;
+
+import java.awt.Color;
+
+/**
+ * Class to calculate a physiological color for display on a computer monitor for a given wavelength
+ * of the light using Bruton's algorithm, see <a href="http://www.midnightkite.com/color.html">COLOR
+ * SCIENCE web page</a> for details.
+ * 
+ * @author Bernd Rinn
+ */
+public class WavelengthColor
+{
+    private final static float NO_GAMMA = 1.0f;
+
+    private final static int MAX_INTENSITY_VALUE = 255;
+
+    private static final int MIN_WAVELENGTH = 380;
+
+    private static final int MAX_WAVELENGTH = 780;
+
+    private static float calcIntensityCorrectionFactor(int wavelength)
+    {
+        float factor;
+        if (wavelength >= MIN_WAVELENGTH && wavelength < 420)
+        {
+            factor = 0.3f + 0.7f * (wavelength - MIN_WAVELENGTH) / (420.0f - MIN_WAVELENGTH);
+        } else if (wavelength >= 420 && wavelength <= 700)
+        {
+            factor = 1.0f;
+        } else if (wavelength > 700 && wavelength <= MAX_WAVELENGTH)
+        {
+            factor = 0.3f + 0.7f * (MAX_WAVELENGTH - wavelength) / (MAX_WAVELENGTH - 700.0f);
+        } else
+        {
+            factor = 0.0f;
+        }
+        return factor;
+    }
+
+    private static int adjust(double value, double factor, double gamma)
+    {
+        if (value == 0.0)
+        {
+            return 0;
+        } else if (gamma == 1.0)
+        {
+            return (int) Math.round(MAX_INTENSITY_VALUE * Math.pow(value * factor, gamma));
+        } else
+        {
+            return (int) Math.round(MAX_INTENSITY_VALUE * value * factor);
+        }
+    }
+
+    /**
+     * Creates a physiological HSB color for the given <var>wavelength<var> in nanometer.
+     * <p>
+     * Does not perform a Gamma correction.
+     */
+    public static PureHSBColor getHSBColorForWavelength(int wavelength)
+    {
+        return PureHSBColor.createFromRGBColor(getRGBColorForWavelength(wavelength, NO_GAMMA));
+    }
+
+    /**
+     * Creates a physiological RGB color for the given <var>wavelength<var> in nanometer.
+     * <p>
+     * Does not perform a Gamma correction.
+     */
+    public static Color getRGBColorForWavelength(int wavelength)
+    {
+        return getRGBColorForWavelength(wavelength, NO_GAMMA);
+    }
+
+    /**
+     * Creates a physiological HSB color for the given <var>wavelength<var> in nano-meters.
+     * <p>
+     * Performs a Gamma correction with the given <var>gamma</var> value.
+     */
+    public static PureHSBColor getHSBColorForWavelength(int wavelength, float gamma)
+    {
+        return PureHSBColor.createFromRGBColor(getRGBColorForWavelength(wavelength, gamma));
+    }
+    /**
+     * Creates a physiological RGB color for the given <var>wavelength<var> in nano-meters.
+     * <p>
+     * Performs a Gamma correction with the given <var>gamma</var> value.
+     */
+    public static Color getRGBColorForWavelength(int wavelength, float gamma)
+    {
+        final float red, green, blue;
+
+        if (wavelength >= MIN_WAVELENGTH && wavelength <= 440)
+        {
+            red = -(wavelength - 440.0f) / (440.0f - MIN_WAVELENGTH);
+            green = 0.0f;
+            blue = 1.0f;
+        } else if (wavelength > 440 && wavelength <= 490)
+        {
+            red = 0.0f;
+            green = (wavelength - 440.0f) / (490.0f - 440.0f);
+            blue = 1.0f;
+        } else if (wavelength > 490 && wavelength <= 510)
+        {
+            red = 0.0f;
+            green = 1.0f;
+            blue = -(wavelength - 510.0f) / (510.0f - 490.0f);
+
+        } else if (wavelength > 510 && wavelength <= 580)
+        {
+            red = (wavelength - 510.0f) / (580.0f - 510.0f);
+            green = 1.0f;
+            blue = 0.0f;
+        } else if (wavelength > 580 && wavelength <= 645)
+        {
+            red = 1.0f;
+            green = -(wavelength - 645.0f) / (645.0f - 580.0f);
+            blue = 0.0f;
+        } else if (wavelength > 645 && wavelength <= MAX_WAVELENGTH)
+        {
+            red = 1.0f;
+            green = 0.0f;
+            blue = 0.0f;
+        } else
+        {
+            // Wavelength is not visible.
+            red = 0.0f;
+            green = 0.0f;
+            blue = 0.0f;
+        }
+
+        final double factor = calcIntensityCorrectionFactor(wavelength);
+
+        final int r = adjust(red, factor, gamma);
+        final int g = adjust(green, factor, gamma);
+        final int b = adjust(blue, factor, gamma);
+
+        return new Color(r, g, b);
+    }
+
+}
\ No newline at end of file