Initial Contribution
diff --git a/awt/javax/imageio/ImageWriteParam.java b/awt/javax/imageio/ImageWriteParam.java
new file mode 100644
index 0000000..d32fa59
--- /dev/null
+++ b/awt/javax/imageio/ImageWriteParam.java
@@ -0,0 +1,633 @@
+/*
+ *  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.
+ */
+/**
+ * @author Rustem V. Rafikov
+ * @version $Revision: 1.3 $
+ */
+package javax.imageio;
+
+import java.util.Locale;
+import java.awt.*;
+
+/**
+ * The ImageWriteParam class provides information to an ImageWriter 
+ * about how an image is to be encoded.
+ */
+public class ImageWriteParam extends IIOParam {
+
+    /** 
+     * The Constant MODE_DISABLED indicates that 
+     * stream is not tiled, progressive, or compressed.
+     */
+    public static final int MODE_DISABLED = 0;
+    
+    /** 
+     * The Constant MODE_DEFAULT indicates that the stream will be tiled, 
+     * progressive, or compressed according to the plug-in's default. 
+     */
+    public static final int MODE_DEFAULT = 1;
+    
+    /** 
+     * The Constant MODE_EXPLICIT indicates that the stream will be tiled,
+     * progressive, or compressed according to current settings
+     * which are defined by set methods. 
+     */
+    public static final int MODE_EXPLICIT = 2;
+    
+    /** 
+     * The Constant MODE_COPY_FROM_METADATA indicates that the stream
+     * will be tiled, progressive, or compressed according to
+     * stream or image metadata. 
+     */
+    public static final int MODE_COPY_FROM_METADATA = 3;
+    
+    /** Whether the ImageWriter can write tiles. */
+    protected boolean canWriteTiles = false;
+    
+    /** The tiling mode. */
+    protected int tilingMode = MODE_COPY_FROM_METADATA;
+    
+    /** The preferred tile sizes. */
+    protected Dimension[] preferredTileSizes = null;
+    
+    /** The tiling set. */
+    protected boolean tilingSet = false;
+    
+    /** The tile width. */
+    protected int tileWidth = 0;
+    
+    /** The tile height. */
+    protected int tileHeight = 0;
+    
+    /** Whether the ImageWriter can offset tiles. */
+    protected boolean canOffsetTiles = false;
+    
+    /** The tile grid x offset. */
+    protected int tileGridXOffset = 0;
+    
+    /** The tile grid y offset. */
+    protected int tileGridYOffset = 0;
+    
+    /** Whether the ImageWriter can write in progressive mode. */
+    protected boolean canWriteProgressive = false;
+    
+    /** The progressive mode. */
+    protected int progressiveMode = MODE_COPY_FROM_METADATA;
+    
+    /** Whether the ImageWriter can write in compressed mode. */
+    protected boolean canWriteCompressed = false;
+    
+    /** The compression mode. */
+    protected int compressionMode = MODE_COPY_FROM_METADATA;
+    
+    /** The compression types. */
+    protected String[] compressionTypes = null;
+    
+    /** The compression type. */
+    protected String compressionType = null;
+    
+    /** The compression quality. */
+    protected float compressionQuality = 1.0f;
+    
+    /** The locale. */
+    protected Locale locale = null;
+
+    /**
+     * Instantiates a new ImageWriteParam.
+     */
+    protected ImageWriteParam() {}
+
+    /**
+     * Instantiates a new ImageWriteParam with the specified Locale.
+     * 
+     * @param locale the Locale.
+     */
+    public ImageWriteParam(Locale locale) {
+        this.locale = locale;
+
+    }
+
+    /**
+     * Gets the mode for writing the stream in a progressive sequence. 
+     * 
+     * @return the current progressive mode.
+     */
+    public int getProgressiveMode() {
+        if (canWriteProgressive()) {
+            return progressiveMode;
+        }
+        throw new UnsupportedOperationException("progressive mode is not supported");
+    }
+
+    /**
+     * Returns true if images can be written using 
+     * increasing quality passes by progressive.  
+     * 
+     * @return true if images can be written using 
+     * increasing quality passes by progressive, false otherwise.
+     */
+    public boolean canWriteProgressive() {
+        return canWriteProgressive;
+    }
+
+    /**
+     * Sets the progressive mode which defines whether the stream 
+     * contains a progressive sequence of increasing quality
+     * during writing. The progressive mode should be one of
+     * the following values: MODE_DISABLED, MODE_DEFAULT, or
+     * MODE_COPY_FROM_METADATA.
+     * 
+     * @param mode the new progressive mode.
+     */
+    public void setProgressiveMode(int mode) {
+        if (canWriteProgressive()) {
+            if (mode < MODE_DISABLED || mode > MODE_COPY_FROM_METADATA || mode == MODE_EXPLICIT) {
+                throw new IllegalArgumentException("mode is not supported");
+            }
+            this.progressiveMode = mode;
+        }
+        throw new UnsupportedOperationException("progressive mode is not supported");
+    }
+
+    /**
+     * Returns true if the writer can use tiles with non zero 
+     * grid offsets while writing. 
+     * 
+     * @return true if the writer can use tiles with non zero 
+     * grid offsets while writing, false otherwise.
+     */
+    public boolean canOffsetTiles() {
+        return canOffsetTiles;
+    }
+
+    /**
+     * Returns true if this writer can write images with 
+     * compression.  
+     * 
+     * @return true, true if this writer can write images with 
+     * compression, false otherwise.
+     */
+    public boolean canWriteCompressed() {
+        return canWriteCompressed;
+    }
+
+    /**
+     * Returns true if the writer can write tiles.
+     * 
+     * @return true if the writer can write tiles, false otherwise.
+     */
+    public boolean canWriteTiles() {
+        return canWriteTiles;
+    }
+
+    /**
+     * Check write compressed.
+     */
+    private final void checkWriteCompressed() {
+        if (!canWriteCompressed()) {
+            throw new UnsupportedOperationException("Compression not supported.");
+        }
+    }
+
+    /**
+     * Check compression mode.
+     */
+    private final void checkCompressionMode() {
+        if (getCompressionMode() != MODE_EXPLICIT) {
+            throw new IllegalStateException("Compression mode not MODE_EXPLICIT!");
+        }
+    }
+
+    /**
+     * Check compression type.
+     */
+    private final void checkCompressionType() {
+        if (getCompressionTypes() != null && getCompressionType() == null) {
+            throw new IllegalStateException("No compression type set!");
+        }
+    }
+
+    /**
+     * Gets the compression mode.
+     * 
+     * @return the compression mode if it's supported.
+     */
+    public int getCompressionMode() {
+        checkWriteCompressed();
+        return compressionMode;
+    }
+
+    /**
+     * Gets the an array of supported compression types.
+     * 
+     * @return the an array of supported compression types.
+     */
+    public String[] getCompressionTypes() {
+        checkWriteCompressed();
+        if (compressionTypes != null) {
+            return compressionTypes.clone();
+        }
+        return null;
+    }
+
+    /**
+     * Gets the current compression type, or returns null.
+     * 
+     * @return the current compression type, or returns null 
+     * if it is not set.
+     */
+    public String getCompressionType() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        return compressionType;
+    }
+
+    /**
+     * Gets a bit rate which represents an estimate of the number of bits 
+     * of output data for each bit of input image data with the specified 
+     * quality.
+     * 
+     * @param quality the quality.
+     * 
+     * @return an estimate of the bit rate, or -1.0F if there is no 
+     * estimate. 
+     */
+    public float getBitRate(float quality) {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        if (quality < 0 || quality > 1) {
+            throw new IllegalArgumentException("Quality out-of-bounds!");
+        }
+        return -1.0f;
+    }
+
+    /**
+     * Gets the compression quality.
+     * 
+     * @return the compression quality.
+     */
+    public float getCompressionQuality() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        return compressionQuality;
+    }
+
+    /**
+     * Gets the array of compression quality descriptions.
+     * 
+     * @return the string array of compression quality descriptions.
+     */
+    public String[] getCompressionQualityDescriptions() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        return null;
+    }
+
+    /**
+     * Gets an array of floats which decribe 
+     * compression quality levels. 
+     * 
+     * @return the array of compression quality values.
+     */
+    public float[] getCompressionQualityValues() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        return null;
+    }
+
+    /**
+     * Gets the locale of this ImageWriteParam.
+     * 
+     * @return the locale of this ImageWriteParam.
+     */
+    public Locale getLocale() {
+        return locale;
+    }
+
+    /**
+     * Gets the current compression type using the current Locale. 
+     * 
+     * @return the current compression type using the current Locale.
+     */
+    public String getLocalizedCompressionTypeName() {
+        checkWriteCompressed();
+        checkCompressionMode();
+
+        String compressionType = getCompressionType();
+        if (compressionType == null) {
+            throw new IllegalStateException("No compression type set!");
+        }
+        return compressionType;
+
+    }
+
+    /**
+     * Check tiling.
+     */
+    private final void checkTiling() {
+        if (!canWriteTiles()) {
+            throw new UnsupportedOperationException("Tiling not supported!");
+        }
+    }
+
+    /**
+     * Check tiling mode.
+     */
+    private final void checkTilingMode() {
+        if (getTilingMode() != MODE_EXPLICIT) {
+            throw new IllegalStateException("Tiling mode not MODE_EXPLICIT!");
+        }
+    }
+
+    /**
+     * Check tiling params.
+     */
+    private final void checkTilingParams() {
+        if (!tilingSet) {
+            throw new IllegalStateException("Tiling parameters not set!");
+        }
+    }
+
+    /**
+     * Gets the tiling mode if tiling is supported.
+     * 
+     * @return the tiling mode if tiling is supported.
+     */
+    public int getTilingMode() {
+        checkTiling();
+        return tilingMode;
+    }
+
+    /**
+     * Gets an array of Dimensions giving the sizes of the tiles as 
+     * they are encoded in the output file or stream. 
+     * 
+     * @return the preferred tile sizes.
+     */
+    public Dimension[] getPreferredTileSizes() {
+        checkTiling();
+        if (preferredTileSizes == null) {
+            return null;
+        }
+
+        Dimension[] retval = new Dimension[preferredTileSizes.length];
+        for (int i = 0; i < preferredTileSizes.length; i++) {
+            retval[i] = new Dimension(retval[i]);
+        }
+        return retval;
+    }
+
+    /**
+     * Gets the tile grid X offset for encoding.
+     * 
+     * @return the tile grid X offset for encoding.
+     */
+    public int getTileGridXOffset() {
+        checkTiling();
+        checkTilingMode();
+        checkTilingParams();
+        return tileGridXOffset;
+    }
+
+    /**
+     * Gets the tile grid Y offset for encoding.
+     * 
+     * @return the tile grid Y offset for encoding.
+     */
+    public int getTileGridYOffset() {
+        checkTiling();
+        checkTilingMode();
+        checkTilingParams();
+        return tileGridYOffset;
+    }
+
+    /**
+     * Gets the tile height in an image as it is written to the 
+     * output stream.
+     * 
+     * @return the tile height in an image as it is written to the 
+     * output stream.
+     */
+    public int getTileHeight() {
+        checkTiling();
+        checkTilingMode();
+        checkTilingParams();
+        return tileHeight;
+    }
+
+    /**
+     * Gets the tile width in an image as it is written to the 
+     * output stream.
+     * 
+     * @return the tile width in an image as it is written to the 
+     * output stream.
+     */
+    public int getTileWidth() {
+        checkTiling();
+        checkTilingMode();
+        checkTilingParams();
+        return tileWidth;
+    }
+
+    /**
+     * Checks if the current compression type has lossless 
+     * compression or not. 
+     * 
+     * @return true, if the current compression type has lossless 
+     * compression, false otherwise.
+     */
+    public boolean isCompressionLossless() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        return true;
+    }
+
+    /**
+     * Removes current compression type.
+     */
+    public void unsetCompression() {
+        checkWriteCompressed();
+        checkCompressionMode();
+        compressionType = null;
+        compressionQuality = 1;
+    }
+
+    /**
+     * Sets the compression mode to the specified value.
+     * The specified mode can be one of the predefined
+     * constants: MODE_DEFAULT, MODE_DISABLED, MODE_EXPLICIT, 
+     * or MODE_COPY_FROM_METADATA.
+     *  
+     * @param mode the new compression mode to be set.
+     */
+    public void setCompressionMode(int mode) {
+        checkWriteCompressed();
+        switch (mode) {
+            case MODE_EXPLICIT: {
+                compressionMode = mode;
+                unsetCompression();
+                break;
+            }
+            case MODE_COPY_FROM_METADATA:
+            case MODE_DISABLED:
+            case MODE_DEFAULT: {
+                compressionMode = mode;
+                break;
+            }
+            default: {
+                throw new IllegalArgumentException("Illegal value for mode!");
+            }
+        }
+    }
+
+    /**
+     * Sets the compression quality. The value should be between 0 and 1.
+     * 
+     * @param quality the new compression quality, 
+     * float value between 0 and 1. 
+     */
+    public void setCompressionQuality(float quality) {
+        checkWriteCompressed();
+        checkCompressionMode();
+        checkCompressionType();
+        if (quality < 0 || quality > 1) {
+            throw new IllegalArgumentException("Quality out-of-bounds!");
+        }
+        compressionQuality = quality;
+    }
+
+    /**
+     * Sets the compression type. The specified string
+     * should be one of the values returned 
+     * by getCompressionTypes method.
+     * 
+     * @param compressionType the new compression type.
+     */
+    public void setCompressionType(String compressionType) {
+        checkWriteCompressed();
+        checkCompressionMode();
+
+        if (compressionType == null) { // Don't check anything
+            this.compressionType = null;
+        } else {
+            String[] compressionTypes = getCompressionTypes();
+            if (compressionTypes == null) {
+                throw new UnsupportedOperationException("No settable compression types");
+            }
+
+            for (int i = 0; i < compressionTypes.length; i++) {
+                if (compressionTypes[i].equals(compressionType)) {
+                    this.compressionType = compressionType;
+                    return;
+                }
+            }
+
+            // Compression type is not in the list.
+            throw new IllegalArgumentException("Unknown compression type!");
+        }
+    }
+
+    /**
+     * Sets the instruction that tiling should be performed for 
+     * the image in the output stream with the specified parameters. 
+     * 
+     * @param tileWidth the tile's width.
+     * @param tileHeight the tile's height.
+     * @param tileGridXOffset the tile grid's x offset.
+     * @param tileGridYOffset the tile grid's y offset.
+     */
+    public void setTiling(int tileWidth, int tileHeight, int tileGridXOffset, int tileGridYOffset) {
+        checkTiling();
+        checkTilingMode();
+
+        if (!canOffsetTiles() && (tileGridXOffset != 0 || tileGridYOffset != 0)) {
+            throw new UnsupportedOperationException("Can't offset tiles!");
+        }
+
+        if (tileWidth <=0 || tileHeight <= 0) {
+            throw new IllegalArgumentException("tile dimensions are non-positive!");
+        }
+
+        Dimension preferredTileSizes[] = getPreferredTileSizes();
+        if (preferredTileSizes != null) {
+            for (int i = 0; i < preferredTileSizes.length; i+=2) {
+                Dimension minSize = preferredTileSizes[i];
+                Dimension maxSize = preferredTileSizes[i+1];
+                if (
+                        tileWidth < minSize.width || tileWidth > maxSize.width ||
+                        tileHeight < minSize.height || tileHeight > maxSize.height
+                ) {
+                    throw new IllegalArgumentException("Illegal tile size!");
+                }
+            }
+        }
+
+        tilingSet = true;
+        this.tileWidth = tileWidth;
+        this.tileHeight = tileHeight;
+        this.tileGridXOffset = tileGridXOffset;
+        this.tileGridYOffset = tileGridYOffset;
+    }
+
+    /**
+     * Clears all tiling settings.
+     */
+    public void unsetTiling() {
+        checkTiling();
+        checkTilingMode();
+
+        tilingSet = false;
+        tileWidth = 0;
+        tileHeight = 0;
+        tileGridXOffset = 0;
+        tileGridYOffset = 0;
+    }
+
+    /**
+     * Sets the tiling mode. The specified mode should be one of the 
+     * following values: MODE_DISABLED, MODE_DEFAULT, MODE_EXPLICIT,
+     * or MODE_COPY_FROM_METADATA.
+     * 
+     * @param mode the new tiling mode.
+     */
+    public void setTilingMode(int mode) {
+        checkTiling();
+
+        switch (mode) {
+            case MODE_EXPLICIT: {
+                tilingMode = mode;
+                unsetTiling();
+                break;
+            }
+            case MODE_COPY_FROM_METADATA:
+            case MODE_DISABLED:
+            case MODE_DEFAULT: {
+                tilingMode = mode;
+                break;
+            }
+            default: {
+                throw new IllegalArgumentException("Illegal value for mode!");
+            }
+        }
+    }
+}
+