diff --git a/src/java/org/apache/xmlgraphics/java2d/color/ColorConverter.java b/src/java/org/apache/xmlgraphics/java2d/color/ColorConverter.java
index 24a06b5..25dc7d6 100644
--- a/src/java/org/apache/xmlgraphics/java2d/color/ColorConverter.java
+++ b/src/java/org/apache/xmlgraphics/java2d/color/ColorConverter.java
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-/* $Id:$ */
-
-package org.apache.xmlgraphics.java2d.color;
-
-import java.awt.Color;
-
-/**
- * Utility for implementing a color conversion scheme.
- */
-public interface ColorConverter {
-
-    /**
-     * @param color to convert
-    * @return converted color
-    */
-
-    Color convert(Color color);
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/* $Id$ */
+
+package org.apache.xmlgraphics.java2d.color;
+
+import java.awt.Color;
+
+/**
+ * Utility for implementing a color conversion scheme.
+ */
+public interface ColorConverter {
+
+    /**
+     * @param color to convert
+    * @return converted color
+    */
+
+    Color convert(Color color);
+
+}
diff --git a/src/java/org/apache/xmlgraphics/java2d/color/ColorUtil.java b/src/java/org/apache/xmlgraphics/java2d/color/ColorUtil.java
index 3b35006..9708d85 100644
--- a/src/java/org/apache/xmlgraphics/java2d/color/ColorUtil.java
+++ b/src/java/org/apache/xmlgraphics/java2d/color/ColorUtil.java
@@ -1,165 +1,165 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-/* $Id: ColorUtil.java 815938 2009-09-16 19:38:13Z jeremias $ */
-
-package org.apache.xmlgraphics.java2d.color;
-
-import java.awt.Color;
-
-
-/**
- * Generic Color helper class.
- * <p>
- * This class supports parsing string values into color values and creating
- * color values for strings. It provides a list of standard color names.
- */
-public final class ColorUtil {
-
-    /**
-     * Private constructor since this is an utility class.
-     */
-    private ColorUtil() {
-    }
-
-
-    /**
-     * Lightens up a color for groove, ridge, inset and outset border effects.
-     * @param col the color to lighten up
-     * @param factor factor by which to lighten up (negative values darken the color)
-     * @return the modified color
-     */
-    public static Color lightenColor(Color col, float factor) {
-        // TODO: This function converts the color into the sRGB namespace.
-        // This should be avoided if possible.
-        float[] cols = new float[4];
-        cols = col.getRGBComponents(cols);
-        if (factor > 0) {
-            cols[0] += (1.0 - cols[0]) * factor;
-            cols[1] += (1.0 - cols[1]) * factor;
-            cols[2] += (1.0 - cols[2]) * factor;
-        } else {
-            cols[0] -= cols[0] * -factor;
-            cols[1] -= cols[1] * -factor;
-            cols[2] -= cols[2] * -factor;
-        }
-        return new ColorWithAlternatives(cols[0], cols[1], cols[2], cols[3], null);
-    }
-
-
-
-    /**
-     * Indicates whether the color is a gray value.
-     * @param col the color
-     * @return true if it is a gray value
-     */
-    public static boolean isGray(Color col) {
-        return (col.getRed() == col.getBlue() && col.getRed() == col.getGreen());
-    }
-
-    /**
-     * Creates an uncalibrated CMYK color with the given gray value.
-     * @param black the gray component (0 - 1)
-     * @return the CMYK color
-     */
-    public static Color toCMYKGrayColor(float black) {
-        //Calculated color components
-        float[] cmyk = new float[] {0f, 0f, 0f, 1.0f - black};
-        //Create native color
-        return DeviceCMYKColorSpace.createCMYKColor(cmyk);
-    }
-
-    /**
-     * Converts an arbitrary {@link Color} to a plain sRGB color doing the conversion at the
-     * best possible conversion quality.
-     * @param col the original color
-     * @return the sRGB equivalent
-     */
-    public static Color toSRGBColor(Color col) {
-        if (col.getColorSpace().isCS_sRGB()) {
-            return col; //Don't convert if already sRGB to avoid conversion differences
-        }
-        float[] comps = col.getColorComponents(null);
-        float[] srgb = col.getColorSpace().toRGB(comps);
-        comps = col.getComponents(null);
-        float alpha = comps[comps.length - 1];
-        return new Color(srgb[0], srgb[1], srgb[2], alpha);
-    }
-
-    /**
-     * Checks if two colors are the same color. This check is much more restrictive than
-     * {@link Color#equals(Object)} in that it doesn't only check if both colors result in the
-     * same sRGB value. For example, if two colors not of the same exact class are compared,
-     * they are treated as not the same.
-     * <p>
-     * Note: At the moment, this method only supports {@link Color} and
-     * {@link ColorWithAlternatives} only. Other subclasses of {@link Color} are checked only using
-     * the {@link Color#equals(Object)} method.
-     * @param col1 the first color
-     * @param col2 the second color
-     * @return true if both colors are the same color
-     */
-    public static boolean isSameColor(Color col1, Color col2) {
-        //Check fallback sRGB values first, then go into details
-        if (!col1.equals(col2)) {
-            return false;
-        }
-
-        //Consider same-ness only between colors of the same class (not subclasses)
-        //but consider a ColorWithAlternatives without alternatives to be the same as a Color.
-        Class<?> cl1 = col1.getClass();
-        if (col1 instanceof ColorWithAlternatives
-                && !((ColorWithAlternatives) col1).hasAlternativeColors()) {
-            cl1 = Color.class;
-        }
-        Class<?> cl2 = col2.getClass();
-        if (col2 instanceof ColorWithAlternatives
-                && !((ColorWithAlternatives) col2).hasAlternativeColors()) {
-            cl2 = Color.class;
-        }
-        if (cl1 != cl2) {
-            return false;
-        }
-
-        //Check color space
-        if (!col1.getColorSpace().equals(col2.getColorSpace())) {
-            return false;
-        }
-
-        //Check native components
-        float[] comps1 = col1.getComponents(null);
-        float[] comps2 = col2.getComponents(null);
-        if (comps1.length != comps2.length) {
-            return false;
-        }
-        for (int i = 0, c = comps1.length; i < c; i++) {
-            if (comps1[i] != comps2[i]) {
-                return false;
-            }
-        }
-
-        //Compare alternative colors, order is relevant
-        if (col1 instanceof ColorWithAlternatives && col2 instanceof ColorWithAlternatives) {
-            ColorWithAlternatives ca1 = (ColorWithAlternatives) col1;
-            ColorWithAlternatives ca2 = (ColorWithAlternatives) col2;
-            return ca1.hasSameAlternativeColors(ca2);
-        }
-
-        return true;
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/* $Id$ */
+
+package org.apache.xmlgraphics.java2d.color;
+
+import java.awt.Color;
+
+
+/**
+ * Generic Color helper class.
+ * <p>
+ * This class supports parsing string values into color values and creating
+ * color values for strings. It provides a list of standard color names.
+ */
+public final class ColorUtil {
+
+    /**
+     * Private constructor since this is an utility class.
+     */
+    private ColorUtil() {
+    }
+
+
+    /**
+     * Lightens up a color for groove, ridge, inset and outset border effects.
+     * @param col the color to lighten up
+     * @param factor factor by which to lighten up (negative values darken the color)
+     * @return the modified color
+     */
+    public static Color lightenColor(Color col, float factor) {
+        // TODO: This function converts the color into the sRGB namespace.
+        // This should be avoided if possible.
+        float[] cols = new float[4];
+        cols = col.getRGBComponents(cols);
+        if (factor > 0) {
+            cols[0] += (1.0 - cols[0]) * factor;
+            cols[1] += (1.0 - cols[1]) * factor;
+            cols[2] += (1.0 - cols[2]) * factor;
+        } else {
+            cols[0] -= cols[0] * -factor;
+            cols[1] -= cols[1] * -factor;
+            cols[2] -= cols[2] * -factor;
+        }
+        return new ColorWithAlternatives(cols[0], cols[1], cols[2], cols[3], null);
+    }
+
+
+
+    /**
+     * Indicates whether the color is a gray value.
+     * @param col the color
+     * @return true if it is a gray value
+     */
+    public static boolean isGray(Color col) {
+        return (col.getRed() == col.getBlue() && col.getRed() == col.getGreen());
+    }
+
+    /**
+     * Creates an uncalibrated CMYK color with the given gray value.
+     * @param black the gray component (0 - 1)
+     * @return the CMYK color
+     */
+    public static Color toCMYKGrayColor(float black) {
+        //Calculated color components
+        float[] cmyk = new float[] {0f, 0f, 0f, 1.0f - black};
+        //Create native color
+        return DeviceCMYKColorSpace.createCMYKColor(cmyk);
+    }
+
+    /**
+     * Converts an arbitrary {@link Color} to a plain sRGB color doing the conversion at the
+     * best possible conversion quality.
+     * @param col the original color
+     * @return the sRGB equivalent
+     */
+    public static Color toSRGBColor(Color col) {
+        if (col.getColorSpace().isCS_sRGB()) {
+            return col; //Don't convert if already sRGB to avoid conversion differences
+        }
+        float[] comps = col.getColorComponents(null);
+        float[] srgb = col.getColorSpace().toRGB(comps);
+        comps = col.getComponents(null);
+        float alpha = comps[comps.length - 1];
+        return new Color(srgb[0], srgb[1], srgb[2], alpha);
+    }
+
+    /**
+     * Checks if two colors are the same color. This check is much more restrictive than
+     * {@link Color#equals(Object)} in that it doesn't only check if both colors result in the
+     * same sRGB value. For example, if two colors not of the same exact class are compared,
+     * they are treated as not the same.
+     * <p>
+     * Note: At the moment, this method only supports {@link Color} and
+     * {@link ColorWithAlternatives} only. Other subclasses of {@link Color} are checked only using
+     * the {@link Color#equals(Object)} method.
+     * @param col1 the first color
+     * @param col2 the second color
+     * @return true if both colors are the same color
+     */
+    public static boolean isSameColor(Color col1, Color col2) {
+        //Check fallback sRGB values first, then go into details
+        if (!col1.equals(col2)) {
+            return false;
+        }
+
+        //Consider same-ness only between colors of the same class (not subclasses)
+        //but consider a ColorWithAlternatives without alternatives to be the same as a Color.
+        Class<?> cl1 = col1.getClass();
+        if (col1 instanceof ColorWithAlternatives
+                && !((ColorWithAlternatives) col1).hasAlternativeColors()) {
+            cl1 = Color.class;
+        }
+        Class<?> cl2 = col2.getClass();
+        if (col2 instanceof ColorWithAlternatives
+                && !((ColorWithAlternatives) col2).hasAlternativeColors()) {
+            cl2 = Color.class;
+        }
+        if (cl1 != cl2) {
+            return false;
+        }
+
+        //Check color space
+        if (!col1.getColorSpace().equals(col2.getColorSpace())) {
+            return false;
+        }
+
+        //Check native components
+        float[] comps1 = col1.getComponents(null);
+        float[] comps2 = col2.getComponents(null);
+        if (comps1.length != comps2.length) {
+            return false;
+        }
+        for (int i = 0, c = comps1.length; i < c; i++) {
+            if (comps1[i] != comps2[i]) {
+                return false;
+            }
+        }
+
+        //Compare alternative colors, order is relevant
+        if (col1 instanceof ColorWithAlternatives && col2 instanceof ColorWithAlternatives) {
+            ColorWithAlternatives ca1 = (ColorWithAlternatives) col1;
+            ColorWithAlternatives ca2 = (ColorWithAlternatives) col2;
+            return ca1.hasSameAlternativeColors(ca2);
+        }
+
+        return true;
+    }
+
+}
diff --git a/src/java/org/apache/xmlgraphics/java2d/color/ColorWithAlternatives.java b/src/java/org/apache/xmlgraphics/java2d/color/ColorWithAlternatives.java
index ea945d5..4f4d0d1 100644
--- a/src/java/org/apache/xmlgraphics/java2d/color/ColorWithAlternatives.java
+++ b/src/java/org/apache/xmlgraphics/java2d/color/ColorWithAlternatives.java
@@ -1,212 +1,212 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-/* $Id: ColorExt.java 884117 2009-11-25 14:42:48Z jeremias $ */
-
-package org.apache.xmlgraphics.java2d.color;
-
-import java.awt.Color;
-import java.awt.color.ColorSpace;
-
-/**
- * Extended {@link Color} class allowing to specify a prioritized list of alternative colors.
- * The alternative colors shall be the ones that are preferred if an output format supports them.
- * This is normally used for passing device-specific colors through to the output format.
- * <p>
- * This class only adds a single reference to a color array which should not increase memory
- * consumption by much if no alternative colors are specified.
- * <p>
- * <b>Important:</b> Due to a flaw in {@link Color#equals(Object)}, the <code>equals()</code>
- * method should not be used to compare two colors, especially when used to update the current
- * color for some output format. {@link Color} only takes the sRGB values into account but not
- * more the advanced facets of this class. Use {@link ColorUtil#isSameColor(Color, Color)} for
- * such a check.
- */
-public class ColorWithAlternatives extends Color {
-
-    private static final long serialVersionUID = -6125884937776779150L;
-
-    private Color[] alternativeColors;
-
-    /**
-     * Constructor for RGBA colors.
-     * @param r the red component
-     * @param g the green component
-     * @param b the blue component
-     * @param a the alpha component
-     * @param alternativeColors the prioritized list of alternative colors.
-     * @see Color#Color(float, float, float, float)
-     */
-    public ColorWithAlternatives(float r, float g, float b, float a, Color[] alternativeColors) {
-        super(r, g, b, a);
-        initAlternativeColors(alternativeColors);
-    }
-
-    /**
-     * Constructor for RGB colors.
-     * @param r the red component
-     * @param g the green component
-     * @param b the blue component
-     * @param alternativeColors the prioritized list of alternative colors.
-     * @see Color#Color(float, float, float)
-     */
-    public ColorWithAlternatives(float r, float g, float b, Color[] alternativeColors) {
-        super(r, g, b);
-        initAlternativeColors(alternativeColors);
-    }
-
-    /**
-     * Constructor for RGBA colors.
-     * @param rgba the combined RGBA value
-     * @param hasalpha true if the alpha bits are valid, false otherwise
-     * @param alternativeColors the prioritized list of alternative colors.
-     * @see Color#Color(int, boolean)
-     */
-    public ColorWithAlternatives(int rgba, boolean hasalpha, Color[] alternativeColors) {
-        super(rgba, hasalpha);
-        initAlternativeColors(alternativeColors);
-    }
-
-    /**
-     * Constructor for RGBA colors.
-     * @param r the red component
-     * @param g the green component
-     * @param b the blue component
-     * @param a the alpha component
-     * @param alternativeColors the prioritized list of alternative colors.
-     * @see Color#Color(int, int, int, int)
-     */
-    public ColorWithAlternatives(int r, int g, int b, int a, Color[] alternativeColors) {
-        super(r, g, b, a);
-        initAlternativeColors(alternativeColors);
-    }
-
-    /**
-     * Constructor for RGB colors.
-     * @param r the red component
-     * @param g the green component
-     * @param b the blue component
-     * @param alternativeColors the prioritized list of alternative colors.
-     * @see Color#Color(int, int, int)
-     */
-    public ColorWithAlternatives(int r, int g, int b, Color[] alternativeColors) {
-        super(r, g, b);
-        initAlternativeColors(alternativeColors);
-    }
-
-    /**
-     * Constructor for RGB colors.
-     * @param rgb the combined RGB components
-     * @param alternativeColors the prioritized list of alternative colors.
-     * @see Color#Color(int)
-     */
-    public ColorWithAlternatives(int rgb, Color[] alternativeColors) {
-        super(rgb);
-        initAlternativeColors(alternativeColors);
-    }
-
-    /**
-     * Constructor for colors with an arbitrary color space.
-     * @param cspace the color space
-     * @param components the color components
-     * @param alpha the alpha component
-     * @param alternativeColors the prioritized list of alternative colors.
-     * @see Color#Color(ColorSpace, float[], float)
-     */
-    public ColorWithAlternatives(ColorSpace cspace, float[] components, float alpha,
-            Color[] alternativeColors) {
-        super(cspace, components, alpha);
-        initAlternativeColors(alternativeColors);
-    }
-
-    private void initAlternativeColors(Color[] colors) {
-        if (colors != null) {
-            //Colors are immutable but array are not, so copy
-            this.alternativeColors = new Color[colors.length];
-            System.arraycopy(colors, 0, this.alternativeColors, 0, colors.length);
-        }
-    }
-
-    /**
-     * Returns the list of alternative colors. An empty array will be returned if no alternative
-     * colors are available.
-     * @return the list of alternative colors
-     */
-    public Color[] getAlternativeColors() {
-        if (this.alternativeColors != null) {
-            Color[] cols = new Color[this.alternativeColors.length];
-            System.arraycopy(this.alternativeColors, 0, cols, 0, this.alternativeColors.length);
-            return cols;
-        } else {
-            return new Color[0];
-        }
-    }
-
-    /**
-     * Indicates whether alternative colors are available.
-     * @return true if alternative colors are available.
-     */
-    public boolean hasAlternativeColors() {
-        return this.alternativeColors != null && this.alternativeColors.length > 0;
-    }
-
-    /**
-     * Indicates whether another instance has the same alternative colors.
-     * @param col the color to compare the alternatives to
-     * @return true if the same alternative colors are present
-     */
-    public boolean hasSameAlternativeColors(ColorWithAlternatives col) {
-        if (!hasAlternativeColors()) {
-            return !col.hasAlternativeColors();
-        }
-        // this.hasAlternativeColors()
-        if (!col.hasAlternativeColors()) {
-            return false;
-        }
-        // this.hasAlternativeColors() && col.hasAlternativeColors()
-        Color[] alt1 = getAlternativeColors();
-        Color[] alt2 = col.getAlternativeColors();
-        if (alt1.length != alt2.length) {
-            return false;
-        }
-        for (int i = 0, c = alt1.length; i < c; i++) {
-            Color c1 = alt1[i];
-            Color c2 = alt2[i];
-            if (!ColorUtil.isSameColor(c1, c2)) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Returns the first alternative color found with the given color space type.
-     * @param colorSpaceType the color space type ({@link ColorSpace}.TYPE_*).
-     * @return the requested alternative color or null, if no match was found
-     */
-    public Color getFirstAlternativeOfType(int colorSpaceType) {
-        if (hasAlternativeColors()) {
-            for (int i = 0, c = this.alternativeColors.length; i < c; i++) {
-                if (this.alternativeColors[i].getColorSpace().getType() == colorSpaceType) {
-                    return this.alternativeColors[i];
-                }
-            }
-        }
-        return null;
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/* $Id$ */
+
+package org.apache.xmlgraphics.java2d.color;
+
+import java.awt.Color;
+import java.awt.color.ColorSpace;
+
+/**
+ * Extended {@link Color} class allowing to specify a prioritized list of alternative colors.
+ * The alternative colors shall be the ones that are preferred if an output format supports them.
+ * This is normally used for passing device-specific colors through to the output format.
+ * <p>
+ * This class only adds a single reference to a color array which should not increase memory
+ * consumption by much if no alternative colors are specified.
+ * <p>
+ * <b>Important:</b> Due to a flaw in {@link Color#equals(Object)}, the <code>equals()</code>
+ * method should not be used to compare two colors, especially when used to update the current
+ * color for some output format. {@link Color} only takes the sRGB values into account but not
+ * more the advanced facets of this class. Use {@link ColorUtil#isSameColor(Color, Color)} for
+ * such a check.
+ */
+public class ColorWithAlternatives extends Color {
+
+    private static final long serialVersionUID = -6125884937776779150L;
+
+    private Color[] alternativeColors;
+
+    /**
+     * Constructor for RGBA colors.
+     * @param r the red component
+     * @param g the green component
+     * @param b the blue component
+     * @param a the alpha component
+     * @param alternativeColors the prioritized list of alternative colors.
+     * @see Color#Color(float, float, float, float)
+     */
+    public ColorWithAlternatives(float r, float g, float b, float a, Color[] alternativeColors) {
+        super(r, g, b, a);
+        initAlternativeColors(alternativeColors);
+    }
+
+    /**
+     * Constructor for RGB colors.
+     * @param r the red component
+     * @param g the green component
+     * @param b the blue component
+     * @param alternativeColors the prioritized list of alternative colors.
+     * @see Color#Color(float, float, float)
+     */
+    public ColorWithAlternatives(float r, float g, float b, Color[] alternativeColors) {
+        super(r, g, b);
+        initAlternativeColors(alternativeColors);
+    }
+
+    /**
+     * Constructor for RGBA colors.
+     * @param rgba the combined RGBA value
+     * @param hasalpha true if the alpha bits are valid, false otherwise
+     * @param alternativeColors the prioritized list of alternative colors.
+     * @see Color#Color(int, boolean)
+     */
+    public ColorWithAlternatives(int rgba, boolean hasalpha, Color[] alternativeColors) {
+        super(rgba, hasalpha);
+        initAlternativeColors(alternativeColors);
+    }
+
+    /**
+     * Constructor for RGBA colors.
+     * @param r the red component
+     * @param g the green component
+     * @param b the blue component
+     * @param a the alpha component
+     * @param alternativeColors the prioritized list of alternative colors.
+     * @see Color#Color(int, int, int, int)
+     */
+    public ColorWithAlternatives(int r, int g, int b, int a, Color[] alternativeColors) {
+        super(r, g, b, a);
+        initAlternativeColors(alternativeColors);
+    }
+
+    /**
+     * Constructor for RGB colors.
+     * @param r the red component
+     * @param g the green component
+     * @param b the blue component
+     * @param alternativeColors the prioritized list of alternative colors.
+     * @see Color#Color(int, int, int)
+     */
+    public ColorWithAlternatives(int r, int g, int b, Color[] alternativeColors) {
+        super(r, g, b);
+        initAlternativeColors(alternativeColors);
+    }
+
+    /**
+     * Constructor for RGB colors.
+     * @param rgb the combined RGB components
+     * @param alternativeColors the prioritized list of alternative colors.
+     * @see Color#Color(int)
+     */
+    public ColorWithAlternatives(int rgb, Color[] alternativeColors) {
+        super(rgb);
+        initAlternativeColors(alternativeColors);
+    }
+
+    /**
+     * Constructor for colors with an arbitrary color space.
+     * @param cspace the color space
+     * @param components the color components
+     * @param alpha the alpha component
+     * @param alternativeColors the prioritized list of alternative colors.
+     * @see Color#Color(ColorSpace, float[], float)
+     */
+    public ColorWithAlternatives(ColorSpace cspace, float[] components, float alpha,
+            Color[] alternativeColors) {
+        super(cspace, components, alpha);
+        initAlternativeColors(alternativeColors);
+    }
+
+    private void initAlternativeColors(Color[] colors) {
+        if (colors != null) {
+            //Colors are immutable but array are not, so copy
+            this.alternativeColors = new Color[colors.length];
+            System.arraycopy(colors, 0, this.alternativeColors, 0, colors.length);
+        }
+    }
+
+    /**
+     * Returns the list of alternative colors. An empty array will be returned if no alternative
+     * colors are available.
+     * @return the list of alternative colors
+     */
+    public Color[] getAlternativeColors() {
+        if (this.alternativeColors != null) {
+            Color[] cols = new Color[this.alternativeColors.length];
+            System.arraycopy(this.alternativeColors, 0, cols, 0, this.alternativeColors.length);
+            return cols;
+        } else {
+            return new Color[0];
+        }
+    }
+
+    /**
+     * Indicates whether alternative colors are available.
+     * @return true if alternative colors are available.
+     */
+    public boolean hasAlternativeColors() {
+        return this.alternativeColors != null && this.alternativeColors.length > 0;
+    }
+
+    /**
+     * Indicates whether another instance has the same alternative colors.
+     * @param col the color to compare the alternatives to
+     * @return true if the same alternative colors are present
+     */
+    public boolean hasSameAlternativeColors(ColorWithAlternatives col) {
+        if (!hasAlternativeColors()) {
+            return !col.hasAlternativeColors();
+        }
+        // this.hasAlternativeColors()
+        if (!col.hasAlternativeColors()) {
+            return false;
+        }
+        // this.hasAlternativeColors() && col.hasAlternativeColors()
+        Color[] alt1 = getAlternativeColors();
+        Color[] alt2 = col.getAlternativeColors();
+        if (alt1.length != alt2.length) {
+            return false;
+        }
+        for (int i = 0, c = alt1.length; i < c; i++) {
+            Color c1 = alt1[i];
+            Color c2 = alt2[i];
+            if (!ColorUtil.isSameColor(c1, c2)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns the first alternative color found with the given color space type.
+     * @param colorSpaceType the color space type ({@link ColorSpace}.TYPE_*).
+     * @return the requested alternative color or null, if no match was found
+     */
+    public Color getFirstAlternativeOfType(int colorSpaceType) {
+        if (hasAlternativeColors()) {
+            for (int i = 0, c = this.alternativeColors.length; i < c; i++) {
+                if (this.alternativeColors[i].getColorSpace().getType() == colorSpaceType) {
+                    return this.alternativeColors[i];
+                }
+            }
+        }
+        return null;
+    }
+
+}
diff --git a/test/java/org/apache/xmlgraphics/xmp/XMPPropertyTest.java b/test/java/org/apache/xmlgraphics/xmp/XMPPropertyTest.java
index 8c87546..27bfa78 100644
--- a/test/java/org/apache/xmlgraphics/xmp/XMPPropertyTest.java
+++ b/test/java/org/apache/xmlgraphics/xmp/XMPPropertyTest.java
@@ -1,186 +1,186 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-/* $Id$ */
-
-package org.apache.xmlgraphics.xmp;
-
-import java.io.StringWriter;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-import java.util.Set;
-import java.util.TimeZone;
-
-import javax.xml.transform.stream.StreamResult;
-import javax.xml.transform.stream.StreamSource;
-
-import junit.framework.TestCase;
-
-import org.apache.xmlgraphics.util.QName;
-import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter;
-import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema;
-import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter;
-import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema;
-
-/**
- * Tests property access methods.
- */
-public class XMPPropertyTest extends TestCase {
-
-    public void testPropertyAccess() throws Exception {
-        Metadata xmp = new Metadata();
-        DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
-        assertNull(dc.getContributors());
-
-        dc.addContributor("Contributor1");
-        assertEquals(1, dc.getContributors().length);
-        assertEquals("Contributor1", dc.getContributors()[0]);
-        dc.removeContributor("Contributor1");
-        assertNull(dc.getContributors());
-
-        dc.addContributor("Contributor1");
-        assertEquals(1, dc.getContributors().length);
-        dc.addContributor("Contributor2");
-        assertEquals(2, dc.getContributors().length);
-        assertFalse(dc.removeContributor("DoesNotExist"));
-        assertTrue(dc.removeContributor("Contributor1"));
-        assertEquals(1, dc.getContributors().length);
-        assertTrue(dc.removeContributor("Contributor2"));
-        assertFalse(dc.removeContributor("Contributor2"));
-        assertNull(dc.getContributors());
-    }
-
-    public void testPropertyRemovalLangAlt() throws Exception {
-        Metadata xmp = new Metadata();
-        DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
-
-        //dc:title is a "Lang Alt"
-        dc.setTitle("en", "The title");
-        String title = dc.removeTitle("en");
-        assertEquals("The title", title);
-        dc.setTitle("en", "The title");
-        dc.setTitle("de", "Der Titel");
-        title = dc.removeTitle("en");
-        assertEquals("The title", title);
-        title = dc.removeTitle("en");
-        assertNull(title);
-
-        title = dc.removeTitle("de");
-        assertEquals("Der Titel", title);
-        title = dc.removeTitle("de");
-        assertNull(title);
-    }
-
-    public void testReplaceLangAlt() throws Exception {
-        Metadata xmp = new Metadata();
-        DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
-        dc.setTitle("Default title");
-        StringWriter writer = new StringWriter();
-        XMPSerializer.writeXML(xmp, new StreamResult(writer));
-        String xmpString = writer.toString();
-        xmp = XMPParser.parseXMP(new StreamSource(new java.io.StringReader(xmpString)));
-        dc = DublinCoreSchema.getAdapter(xmp);
-        assertEquals("Default title", dc.getTitle());
-        dc.setTitle("Updated title");
-        XMPProperty prop = xmp.getProperty(new QName(DublinCoreSchema.NAMESPACE, "title"));
-        XMPArray array = prop.getArrayValue();
-        assertNotNull(array);
-        //Check that only one title is present. There used to be a bug that didn't set the
-        //non-qualified value equal to the value qualified with "x-default".
-        assertEquals(1, array.getSize());
-        assertEquals("Updated title", array.getValue(0));
-    }
-
-    public void testPropertyValues() throws Exception {
-        Metadata xmp = new Metadata();
-        DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
-
-        String format = dc.getFormat();
-        assertNull(format);
-
-        dc.setFormat("application/pdf");
-        format = dc.getFormat();
-        assertEquals("application/pdf", format);
-
-        dc.setFormat("image/jpeg");
-        format = dc.getFormat();
-        assertEquals("image/jpeg", format);
-
-        dc.setFormat(null);
-        format = dc.getFormat();
-        assertNull(format);
-
-        dc.setFormat(""); //Empty string same as null value
-        format = dc.getFormat();
-        assertNull(format);
-
-        dc.setTitle("title");
-        String title = dc.getTitle();
-        assertEquals("title", title);
-
-        dc.setTitle("Titel");
-        title = dc.getTitle();
-        assertEquals("Titel", title);
-
-        dc.setTitle(null);
-        title = dc.getTitle();
-        assertNull(title);
-
-        dc.setTitle("");
-        title = dc.getTitle();
-        assertNull(title);
-    }
-
-    public void testDates() throws Exception {
-        Metadata xmp = new Metadata();
-        XMPBasicAdapter basic = XMPBasicSchema.getAdapter(xmp);
-
-        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH);
-        cal.set(2008, Calendar.FEBRUARY, 07, 15, 11, 07);
-        cal.set(Calendar.MILLISECOND, 0);
-        Date dt = cal.getTime();
-
-        assertNull(basic.getCreateDate());
-        basic.setCreateDate(dt);
-        Date dt2 = basic.getCreateDate();
-        assertEquals(dt2, dt);
-    }
-
-    public void testQualifiers() throws Exception {
-        Metadata xmp = new Metadata();
-        XMPBasicAdapter basic = XMPBasicSchema.getAdapter(xmp);
-
-        basic.addIdentifier("x123");
-        basic.setIdentifier("id1", "system1");
-        basic.setIdentifier("12345", "system2");
-
-        String[] ids = basic.getIdentifiers();
-        assertEquals(3, ids.length);
-        Set set = new java.util.HashSet(Arrays.asList(ids));
-        assertTrue(set.contains("x123"));
-        assertTrue(set.contains("id1"));
-        assertTrue(set.contains("12345"));
-
-        assertEquals("id1", basic.getIdentifier("system1"));
-        basic.setIdentifier("id2", "system1");
-        assertEquals("id2", basic.getIdentifier("system1"));
-        assertEquals(3, basic.getIdentifiers().length);
-    }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/* $Id$ */
+
+package org.apache.xmlgraphics.xmp;
+
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Set;
+import java.util.TimeZone;
+
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import junit.framework.TestCase;
+
+import org.apache.xmlgraphics.util.QName;
+import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter;
+import org.apache.xmlgraphics.xmp.schemas.DublinCoreSchema;
+import org.apache.xmlgraphics.xmp.schemas.XMPBasicAdapter;
+import org.apache.xmlgraphics.xmp.schemas.XMPBasicSchema;
+
+/**
+ * Tests property access methods.
+ */
+public class XMPPropertyTest extends TestCase {
+
+    public void testPropertyAccess() throws Exception {
+        Metadata xmp = new Metadata();
+        DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
+        assertNull(dc.getContributors());
+
+        dc.addContributor("Contributor1");
+        assertEquals(1, dc.getContributors().length);
+        assertEquals("Contributor1", dc.getContributors()[0]);
+        dc.removeContributor("Contributor1");
+        assertNull(dc.getContributors());
+
+        dc.addContributor("Contributor1");
+        assertEquals(1, dc.getContributors().length);
+        dc.addContributor("Contributor2");
+        assertEquals(2, dc.getContributors().length);
+        assertFalse(dc.removeContributor("DoesNotExist"));
+        assertTrue(dc.removeContributor("Contributor1"));
+        assertEquals(1, dc.getContributors().length);
+        assertTrue(dc.removeContributor("Contributor2"));
+        assertFalse(dc.removeContributor("Contributor2"));
+        assertNull(dc.getContributors());
+    }
+
+    public void testPropertyRemovalLangAlt() throws Exception {
+        Metadata xmp = new Metadata();
+        DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
+
+        //dc:title is a "Lang Alt"
+        dc.setTitle("en", "The title");
+        String title = dc.removeTitle("en");
+        assertEquals("The title", title);
+        dc.setTitle("en", "The title");
+        dc.setTitle("de", "Der Titel");
+        title = dc.removeTitle("en");
+        assertEquals("The title", title);
+        title = dc.removeTitle("en");
+        assertNull(title);
+
+        title = dc.removeTitle("de");
+        assertEquals("Der Titel", title);
+        title = dc.removeTitle("de");
+        assertNull(title);
+    }
+
+    public void testReplaceLangAlt() throws Exception {
+        Metadata xmp = new Metadata();
+        DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
+        dc.setTitle("Default title");
+        StringWriter writer = new StringWriter();
+        XMPSerializer.writeXML(xmp, new StreamResult(writer));
+        String xmpString = writer.toString();
+        xmp = XMPParser.parseXMP(new StreamSource(new java.io.StringReader(xmpString)));
+        dc = DublinCoreSchema.getAdapter(xmp);
+        assertEquals("Default title", dc.getTitle());
+        dc.setTitle("Updated title");
+        XMPProperty prop = xmp.getProperty(new QName(DublinCoreSchema.NAMESPACE, "title"));
+        XMPArray array = prop.getArrayValue();
+        assertNotNull(array);
+        //Check that only one title is present. There used to be a bug that didn't set the
+        //non-qualified value equal to the value qualified with "x-default".
+        assertEquals(1, array.getSize());
+        assertEquals("Updated title", array.getValue(0));
+    }
+
+    public void testPropertyValues() throws Exception {
+        Metadata xmp = new Metadata();
+        DublinCoreAdapter dc = DublinCoreSchema.getAdapter(xmp);
+
+        String format = dc.getFormat();
+        assertNull(format);
+
+        dc.setFormat("application/pdf");
+        format = dc.getFormat();
+        assertEquals("application/pdf", format);
+
+        dc.setFormat("image/jpeg");
+        format = dc.getFormat();
+        assertEquals("image/jpeg", format);
+
+        dc.setFormat(null);
+        format = dc.getFormat();
+        assertNull(format);
+
+        dc.setFormat(""); //Empty string same as null value
+        format = dc.getFormat();
+        assertNull(format);
+
+        dc.setTitle("title");
+        String title = dc.getTitle();
+        assertEquals("title", title);
+
+        dc.setTitle("Titel");
+        title = dc.getTitle();
+        assertEquals("Titel", title);
+
+        dc.setTitle(null);
+        title = dc.getTitle();
+        assertNull(title);
+
+        dc.setTitle("");
+        title = dc.getTitle();
+        assertNull(title);
+    }
+
+    public void testDates() throws Exception {
+        Metadata xmp = new Metadata();
+        XMPBasicAdapter basic = XMPBasicSchema.getAdapter(xmp);
+
+        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.ENGLISH);
+        cal.set(2008, Calendar.FEBRUARY, 07, 15, 11, 07);
+        cal.set(Calendar.MILLISECOND, 0);
+        Date dt = cal.getTime();
+
+        assertNull(basic.getCreateDate());
+        basic.setCreateDate(dt);
+        Date dt2 = basic.getCreateDate();
+        assertEquals(dt2, dt);
+    }
+
+    public void testQualifiers() throws Exception {
+        Metadata xmp = new Metadata();
+        XMPBasicAdapter basic = XMPBasicSchema.getAdapter(xmp);
+
+        basic.addIdentifier("x123");
+        basic.setIdentifier("id1", "system1");
+        basic.setIdentifier("12345", "system2");
+
+        String[] ids = basic.getIdentifiers();
+        assertEquals(3, ids.length);
+        Set set = new java.util.HashSet(Arrays.asList(ids));
+        assertTrue(set.contains("x123"));
+        assertTrue(set.contains("id1"));
+        assertTrue(set.contains("12345"));
+
+        assertEquals("id1", basic.getIdentifier("system1"));
+        basic.setIdentifier("id2", "system1");
+        assertEquals("id2", basic.getIdentifier("system1"));
+        assertEquals(3, basic.getIdentifiers().length);
+    }
+
+}
